mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Update ISaveDataFileSystemCreator.Create
Update method parameters and rewrite the method to use SaveDataSharedFileStorage. SaveDataFileSystemCreator now requires a FileSystemServer at construction time, so DefaultFsServerObjects must be created after FileSystemServer construction but before FileSystemServer initialization.
This commit is contained in:
parent
d1a49b989a
commit
7294206116
@ -12,7 +12,8 @@ namespace LibHac.FsSrv
|
|||||||
public EmulatedGameCard GameCard { get; set; }
|
public EmulatedGameCard GameCard { get; set; }
|
||||||
public EmulatedSdCard SdCard { get; set; }
|
public EmulatedSdCard SdCard { get; set; }
|
||||||
|
|
||||||
public static DefaultFsServerObjects GetDefaultEmulatedCreators(IFileSystem rootFileSystem, KeySet keySet)
|
public static DefaultFsServerObjects GetDefaultEmulatedCreators(IFileSystem rootFileSystem, KeySet keySet,
|
||||||
|
FileSystemServer fsServer)
|
||||||
{
|
{
|
||||||
var creators = new FileSystemCreatorInterfaces();
|
var creators = new FileSystemCreatorInterfaces();
|
||||||
var gameCard = new EmulatedGameCard(keySet);
|
var gameCard = new EmulatedGameCard(keySet);
|
||||||
@ -25,7 +26,7 @@ namespace LibHac.FsSrv
|
|||||||
creators.StorageOnNcaCreator = new StorageOnNcaCreator(keySet);
|
creators.StorageOnNcaCreator = new StorageOnNcaCreator(keySet);
|
||||||
creators.TargetManagerFileSystemCreator = new TargetManagerFileSystemCreator();
|
creators.TargetManagerFileSystemCreator = new TargetManagerFileSystemCreator();
|
||||||
creators.SubDirectoryFileSystemCreator = new SubDirectoryFileSystemCreator();
|
creators.SubDirectoryFileSystemCreator = new SubDirectoryFileSystemCreator();
|
||||||
creators.SaveDataFileSystemCreator = new SaveDataFileSystemCreator(keySet, null, null);
|
creators.SaveDataFileSystemCreator = new SaveDataFileSystemCreator(fsServer, keySet, null, null);
|
||||||
creators.GameCardStorageCreator = gcStorageCreator;
|
creators.GameCardStorageCreator = gcStorageCreator;
|
||||||
creators.GameCardFileSystemCreator = new EmulatedGameCardFsCreator(gcStorageCreator, gameCard);
|
creators.GameCardFileSystemCreator = new EmulatedGameCardFsCreator(gcStorageCreator, gameCard);
|
||||||
creators.EncryptedFileSystemCreator = new EncryptedFileSystemCreator(keySet);
|
creators.EncryptedFileSystemCreator = new EncryptedFileSystemCreator(keySet);
|
||||||
|
@ -74,10 +74,6 @@ namespace LibHac.FsSrv
|
|||||||
Memory<byte> heapBuffer = GC.AllocateArray<byte>(BufferManagerHeapSize, true);
|
Memory<byte> heapBuffer = GC.AllocateArray<byte>(BufferManagerHeapSize, true);
|
||||||
bufferManager.Initialize(BufferManagerCacheSize, heapBuffer, BufferManagerBlockSize);
|
bufferManager.Initialize(BufferManagerCacheSize, heapBuffer, BufferManagerBlockSize);
|
||||||
|
|
||||||
// Todo: A non-hacky way of initializing the save data creator
|
|
||||||
config.FsCreators.SaveDataFileSystemCreator =
|
|
||||||
new SaveDataFileSystemCreator(config.KeySet, bufferManager, randomGenerator);
|
|
||||||
|
|
||||||
var saveDataIndexerManager = new SaveDataIndexerManager(server.Hos.Fs, Fs.SaveData.SaveIndexerId,
|
var saveDataIndexerManager = new SaveDataIndexerManager(server.Hos.Fs, Fs.SaveData.SaveIndexerId,
|
||||||
new ArrayPoolMemoryResource(), new SdHandleManager(), false);
|
new ArrayPoolMemoryResource(), new SdHandleManager(), false);
|
||||||
|
|
||||||
@ -264,10 +260,5 @@ namespace LibHac.FsSrv
|
|||||||
/// If null, an empty set will be created.
|
/// If null, an empty set will be created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExternalKeySet ExternalKeySet { get; set; }
|
public ExternalKeySet ExternalKeySet { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A keyset used for decrypting content.
|
|
||||||
/// </summary>
|
|
||||||
public KeySet KeySet { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,13 @@ namespace LibHac.FsSrv.FsCreator
|
|||||||
|
|
||||||
Result Create(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
Result Create(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
out ReferenceCountedDisposable<ISaveDataExtraDataAccessor> extraDataAccessor,
|
out ReferenceCountedDisposable<ISaveDataExtraDataAccessor> extraDataAccessor,
|
||||||
ReferenceCountedDisposable<IFileSystem> sourceFileSystem, ulong saveDataId, bool allowDirectorySaveData,
|
ISaveDataFileSystemCacheManager cacheManager, ref ReferenceCountedDisposable<IFileSystem> baseFileSystem,
|
||||||
bool useDeviceUniqueMac, SaveDataType type, ISaveDataCommitTimeStampGetter timeStampGetter);
|
SaveDataSpaceId spaceId, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac,
|
||||||
|
bool isJournalingSupported, bool isMultiCommitSupported, bool openReadOnly, bool openShared,
|
||||||
|
ISaveDataCommitTimeStampGetter timeStampGetter);
|
||||||
|
|
||||||
|
Result CreateExtraDataAccessor(out ReferenceCountedDisposable<ISaveDataExtraDataAccessor> extraDataAccessor,
|
||||||
|
ReferenceCountedDisposable<IFileSystem> sourceFileSystem);
|
||||||
|
|
||||||
void SetSdCardEncryptionSeed(ReadOnlySpan<byte> seed);
|
void SetSdCardEncryptionSeed(ReadOnlySpan<byte> seed);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Common.Keys;
|
using LibHac.Common.Keys;
|
||||||
|
using LibHac.Diag;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.FsSystem;
|
using LibHac.FsSystem;
|
||||||
using LibHac.FsSystem.Save;
|
using LibHac.FsSystem.Save;
|
||||||
|
using LibHac.Util;
|
||||||
|
|
||||||
|
using OpenType = LibHac.FsSrv.SaveDataOpenTypeSetFileStorage.OpenType;
|
||||||
|
|
||||||
namespace LibHac.FsSrv.FsCreator
|
namespace LibHac.FsSrv.FsCreator
|
||||||
{
|
{
|
||||||
@ -13,13 +17,16 @@ namespace LibHac.FsSrv.FsCreator
|
|||||||
private IBufferManager _bufferManager;
|
private IBufferManager _bufferManager;
|
||||||
private RandomDataGenerator _randomGenerator;
|
private RandomDataGenerator _randomGenerator;
|
||||||
|
|
||||||
|
// LibHac Additions
|
||||||
private KeySet _keySet;
|
private KeySet _keySet;
|
||||||
|
private FileSystemServer _fsServer;
|
||||||
|
|
||||||
public SaveDataFileSystemCreator(KeySet keySet, IBufferManager bufferManager,
|
public SaveDataFileSystemCreator(FileSystemServer fsServer, KeySet keySet, IBufferManager bufferManager,
|
||||||
RandomDataGenerator randomGenerator)
|
RandomDataGenerator randomGenerator)
|
||||||
{
|
{
|
||||||
_bufferManager = bufferManager;
|
_bufferManager = bufferManager;
|
||||||
_randomGenerator = randomGenerator;
|
_randomGenerator = randomGenerator;
|
||||||
|
_fsServer = fsServer;
|
||||||
_keySet = keySet;
|
_keySet = keySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,68 +37,92 @@ namespace LibHac.FsSrv.FsCreator
|
|||||||
|
|
||||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
public Result Create(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
out ReferenceCountedDisposable<ISaveDataExtraDataAccessor> extraDataAccessor,
|
out ReferenceCountedDisposable<ISaveDataExtraDataAccessor> extraDataAccessor,
|
||||||
ReferenceCountedDisposable<IFileSystem> sourceFileSystem, ulong saveDataId, bool allowDirectorySaveData,
|
ISaveDataFileSystemCacheManager cacheManager, ref ReferenceCountedDisposable<IFileSystem> baseFileSystem,
|
||||||
bool useDeviceUniqueMac, SaveDataType type, ISaveDataCommitTimeStampGetter timeStampGetter)
|
SaveDataSpaceId spaceId, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac,
|
||||||
|
bool isJournalingSupported, bool isMultiCommitSupported, bool openReadOnly, bool openShared,
|
||||||
|
ISaveDataCommitTimeStampGetter timeStampGetter)
|
||||||
{
|
{
|
||||||
|
Span<byte> saveImageName = stackalloc byte[0x12];
|
||||||
UnsafeHelpers.SkipParamInit(out fileSystem, out extraDataAccessor);
|
UnsafeHelpers.SkipParamInit(out fileSystem, out extraDataAccessor);
|
||||||
|
|
||||||
var saveDataPath = $"/{saveDataId:x16}".ToU8String();
|
Assert.SdkRequiresNotNull(cacheManager);
|
||||||
|
|
||||||
|
var sb = new U8StringBuilder(saveImageName);
|
||||||
|
sb.Append((byte)'/').AppendFormat(saveDataId, 'x', 16);
|
||||||
|
|
||||||
|
Result rc = baseFileSystem.Target.GetEntryType(out DirectoryEntryType type, new U8Span(saveImageName));
|
||||||
|
|
||||||
Result rc = sourceFileSystem.Target.GetEntryType(out DirectoryEntryType entryType, saveDataPath);
|
|
||||||
if (rc.IsFailure())
|
if (rc.IsFailure())
|
||||||
{
|
{
|
||||||
return ResultFs.PathNotFound.Includes(rc) ? ResultFs.TargetNotFound.LogConverted(rc) : rc;
|
return ResultFs.PathNotFound.Includes(rc) ? ResultFs.TargetNotFound.LogConverted(rc) : rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entryType)
|
if (type == DirectoryEntryType.Directory)
|
||||||
{
|
{
|
||||||
case DirectoryEntryType.Directory:
|
if (!allowDirectorySaveData)
|
||||||
if (!allowDirectorySaveData) return ResultFs.InvalidSaveDataEntryType.Log();
|
return ResultFs.InvalidSaveDataEntryType.Log();
|
||||||
|
|
||||||
var subDirFs = new SubdirectoryFileSystem(ref sourceFileSystem);
|
SubdirectoryFileSystem subDirFs = null;
|
||||||
|
ReferenceCountedDisposable<DirectorySaveDataFileSystem> saveFs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
subDirFs = new SubdirectoryFileSystem(ref baseFileSystem);
|
||||||
|
|
||||||
rc = subDirFs.Initialize(saveDataPath);
|
rc = subDirFs.Initialize(new U8Span(saveImageName));
|
||||||
if (rc.IsFailure())
|
|
||||||
{
|
|
||||||
subDirFs.Dispose();
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPersistentSaveData = type != SaveDataType.Temporary;
|
|
||||||
bool isUserSaveData = type == SaveDataType.Account || type == SaveDataType.Device;
|
|
||||||
|
|
||||||
rc = DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, subDirFs,
|
|
||||||
timeStampGetter, _randomGenerator, isPersistentSaveData, isUserSaveData, true, null);
|
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
ReferenceCountedDisposable<DirectorySaveDataFileSystem> sharedSaveFs = null;
|
saveFs = DirectorySaveDataFileSystem.CreateShared(Shared.Move(ref subDirFs), _fsServer.Hos.Fs);
|
||||||
try
|
|
||||||
{
|
|
||||||
sharedSaveFs = new ReferenceCountedDisposable<DirectorySaveDataFileSystem>(saveFs);
|
|
||||||
fileSystem = sharedSaveFs.AddReference<IFileSystem>();
|
|
||||||
extraDataAccessor = sharedSaveFs.AddReference<ISaveDataExtraDataAccessor>();
|
|
||||||
|
|
||||||
return Result.Success;
|
rc = saveFs.Target.Initialize(timeStampGetter, _randomGenerator, isJournalingSupported,
|
||||||
}
|
isMultiCommitSupported, !openReadOnly);
|
||||||
finally
|
|
||||||
{
|
|
||||||
sharedSaveFs?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
case DirectoryEntryType.File:
|
|
||||||
rc = sourceFileSystem.Target.OpenFile(out IFile saveDataFile, saveDataPath, OpenMode.ReadWrite);
|
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
var saveDataStorage = new DisposingFileStorage(saveDataFile);
|
fileSystem = saveFs.AddReference<IFileSystem>();
|
||||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(new SaveDataFileSystem(_keySet,
|
extraDataAccessor = saveFs.AddReference<ISaveDataExtraDataAccessor>();
|
||||||
saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, false));
|
|
||||||
|
|
||||||
// Todo: ISaveDataExtraDataAccessor
|
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
default:
|
}
|
||||||
throw new ArgumentOutOfRangeException();
|
finally
|
||||||
|
{
|
||||||
|
subDirFs?.Dispose();
|
||||||
|
saveFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReferenceCountedDisposable<IStorage> fileStorage = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Optional<OpenType> openType =
|
||||||
|
openShared ? new Optional<OpenType>(OpenType.Normal) : new Optional<OpenType>();
|
||||||
|
|
||||||
|
rc = _fsServer.OpenSaveDataStorage(out fileStorage, ref baseFileSystem, spaceId, saveDataId,
|
||||||
|
OpenMode.ReadWrite, openType);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
if (!isJournalingSupported)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: Properly handle shared storage
|
||||||
|
fileSystem = new ReferenceCountedDisposable<IFileSystem>(new SaveDataFileSystem(_keySet,
|
||||||
|
fileStorage.Target, IntegrityCheckLevel.ErrorOnInvalid, false));
|
||||||
|
|
||||||
|
// Todo: ISaveDataExtraDataAccessor
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
fileStorage?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result CreateExtraDataAccessor(
|
||||||
|
out ReferenceCountedDisposable<ISaveDataExtraDataAccessor> extraDataAccessor,
|
||||||
|
ReferenceCountedDisposable<IFileSystem> sourceFileSystem)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSdCardEncryptionSeed(ReadOnlySpan<byte> seed)
|
public void SetSdCardEncryptionSeed(ReadOnlySpan<byte> seed)
|
||||||
|
@ -167,11 +167,14 @@ namespace LibHac.FsSrv
|
|||||||
{
|
{
|
||||||
using ScopedLock<SdkRecursiveMutexType> scopedLock = _extraDataCacheManager.GetScopedLock();
|
using ScopedLock<SdkRecursiveMutexType> scopedLock = _extraDataCacheManager.GetScopedLock();
|
||||||
|
|
||||||
// Todo: Update ISaveDataFileSystemCreator
|
bool openShared = SaveDataProperties.IsSharedOpenNeeded(type);
|
||||||
|
bool isMultiCommitSupported = SaveDataProperties.IsMultiCommitSupported(type);
|
||||||
|
bool isJournalingSupported = SaveDataProperties.IsJournalingSupported(type);
|
||||||
bool useDeviceUniqueMac = IsDeviceUniqueMac(spaceId);
|
bool useDeviceUniqueMac = IsDeviceUniqueMac(spaceId);
|
||||||
|
|
||||||
rc = _config.SaveFsCreator.Create(out saveFs, out extraDataAccessor, saveDirectoryFs,
|
rc = _config.SaveFsCreator.Create(out saveFs, out extraDataAccessor, _saveDataFsCacheManager,
|
||||||
saveDataId, allowDirectorySaveData, useDeviceUniqueMac, type, _timeStampGetter);
|
ref saveDirectoryFs, spaceId, saveDataId, allowDirectorySaveData, useDeviceUniqueMac,
|
||||||
|
isJournalingSupported, isMultiCommitSupported, openReadOnly, openShared, _timeStampGetter);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
saveDataFs = Shared.Move(ref saveFs);
|
saveDataFs = Shared.Move(ref saveFs);
|
||||||
@ -188,7 +191,6 @@ namespace LibHac.FsSrv
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
saveFs?.Dispose();
|
saveFs?.Dispose();
|
||||||
cachedSaveDataFs?.Dispose();
|
|
||||||
extraDataAccessor?.Dispose();
|
extraDataAccessor?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,8 +206,6 @@ namespace LibHac.FsSrv
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
saveDirectoryFs?.Dispose();
|
saveDirectoryFs?.Dispose();
|
||||||
// ReSharper disable once ExpressionIsAlwaysNull
|
|
||||||
// ReSharper disable once ConstantConditionalAccessQualifier
|
|
||||||
cachedSaveDataFs?.Dispose();
|
cachedSaveDataFs?.Dispose();
|
||||||
saveDataFs?.Dispose();
|
saveDataFs?.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,9 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
// Todo: Unique file system for disposal
|
// Todo: Unique file system for disposal
|
||||||
private int _openWritableFileCount;
|
private int _openWritableFileCount;
|
||||||
private bool _isPersistentSaveData;
|
private bool _isJournalingSupported;
|
||||||
private bool _canCommitProvisionally;
|
private bool _isMultiCommitSupported;
|
||||||
private bool _useTransactions;
|
private bool _isJournalingEnabled;
|
||||||
|
|
||||||
// Additions to support extra data
|
// Additions to support extra data
|
||||||
private ISaveDataCommitTimeStampGetter _timeStampGetter;
|
private ISaveDataCommitTimeStampGetter _timeStampGetter;
|
||||||
@ -124,12 +124,12 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
public static Result CreateNew(out DirectorySaveDataFileSystem created, IFileSystem baseFileSystem,
|
public static Result CreateNew(out DirectorySaveDataFileSystem created, IFileSystem baseFileSystem,
|
||||||
ISaveDataCommitTimeStampGetter timeStampGetter, RandomDataGenerator randomGenerator,
|
ISaveDataCommitTimeStampGetter timeStampGetter, RandomDataGenerator randomGenerator,
|
||||||
bool isPersistentSaveData, bool canCommitProvisionally, bool useTransactions,
|
bool isJournalingSupported, bool isMultiCommitSupported, bool isJournalingEnabled,
|
||||||
FileSystemClient fsClient)
|
FileSystemClient fsClient)
|
||||||
{
|
{
|
||||||
var obj = new DirectorySaveDataFileSystem(baseFileSystem, fsClient);
|
var obj = new DirectorySaveDataFileSystem(baseFileSystem, fsClient);
|
||||||
Result rc = obj.Initialize(timeStampGetter, randomGenerator, isPersistentSaveData, canCommitProvisionally,
|
Result rc = obj.Initialize(timeStampGetter, randomGenerator, isJournalingSupported, isMultiCommitSupported,
|
||||||
useTransactions);
|
isJournalingEnabled);
|
||||||
|
|
||||||
if (rc.IsSuccess())
|
if (rc.IsSuccess())
|
||||||
{
|
{
|
||||||
@ -143,10 +143,17 @@ namespace LibHac.FsSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Result CreateNew(out DirectorySaveDataFileSystem created, IFileSystem baseFileSystem,
|
public static Result CreateNew(out DirectorySaveDataFileSystem created, IFileSystem baseFileSystem,
|
||||||
bool isPersistentSaveData, bool canCommitProvisionally, bool useTransactions)
|
bool isJournalingSupported, bool isMultiCommitSupported, bool isJournalingEnabled)
|
||||||
{
|
{
|
||||||
return CreateNew(out created, baseFileSystem, null, null, isPersistentSaveData, canCommitProvisionally,
|
return CreateNew(out created, baseFileSystem, null, null, isJournalingSupported, isMultiCommitSupported,
|
||||||
useTransactions, null);
|
isJournalingEnabled, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReferenceCountedDisposable<DirectorySaveDataFileSystem> CreateShared(IFileSystem baseFileSystem,
|
||||||
|
FileSystemClient fsClient)
|
||||||
|
{
|
||||||
|
var fileSystem = new DirectorySaveDataFileSystem(baseFileSystem, fsClient);
|
||||||
|
return new ReferenceCountedDisposable<DirectorySaveDataFileSystem>(fileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -181,17 +188,17 @@ namespace LibHac.FsSystem
|
|||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result Initialize(bool isPersistentSaveData, bool canCommitProvisionally, bool useTransactions)
|
public Result Initialize(bool isJournalingSupported, bool isMultiCommitSupported, bool isJournalingEnabled)
|
||||||
{
|
{
|
||||||
return Initialize(null, null, isPersistentSaveData, canCommitProvisionally, useTransactions);
|
return Initialize(null, null, isJournalingSupported, isMultiCommitSupported, isJournalingEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result Initialize(ISaveDataCommitTimeStampGetter timeStampGetter, RandomDataGenerator randomGenerator,
|
public Result Initialize(ISaveDataCommitTimeStampGetter timeStampGetter, RandomDataGenerator randomGenerator,
|
||||||
bool isPersistentSaveData, bool canCommitProvisionally, bool useTransactions)
|
bool isJournalingSupported, bool isMultiCommitSupported, bool isJournalingEnabled)
|
||||||
{
|
{
|
||||||
_isPersistentSaveData = isPersistentSaveData;
|
_isJournalingSupported = isJournalingSupported;
|
||||||
_canCommitProvisionally = canCommitProvisionally;
|
_isMultiCommitSupported = isMultiCommitSupported;
|
||||||
_useTransactions = useTransactions;
|
_isJournalingEnabled = isJournalingEnabled;
|
||||||
_timeStampGetter = timeStampGetter ?? _timeStampGetter;
|
_timeStampGetter = timeStampGetter ?? _timeStampGetter;
|
||||||
_randomGenerator = randomGenerator ?? _randomGenerator;
|
_randomGenerator = randomGenerator ?? _randomGenerator;
|
||||||
|
|
||||||
@ -205,7 +212,7 @@ namespace LibHac.FsSystem
|
|||||||
rc = _baseFs.CreateDirectory(WorkingDirectoryPath);
|
rc = _baseFs.CreateDirectory(WorkingDirectoryPath);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (_isPersistentSaveData)
|
if (_isJournalingSupported)
|
||||||
{
|
{
|
||||||
rc = _baseFs.CreateDirectory(CommittedDirectoryPath);
|
rc = _baseFs.CreateDirectory(CommittedDirectoryPath);
|
||||||
|
|
||||||
@ -215,15 +222,15 @@ namespace LibHac.FsSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only the working directory is needed for temporary savedata
|
// Only the working directory is needed for non-journaling savedata
|
||||||
if (!_isPersistentSaveData)
|
if (!_isJournalingSupported)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
rc = _baseFs.GetEntryType(out _, CommittedDirectoryPath);
|
rc = _baseFs.GetEntryType(out _, CommittedDirectoryPath);
|
||||||
|
|
||||||
if (rc.IsSuccess())
|
if (rc.IsSuccess())
|
||||||
{
|
{
|
||||||
if (!_useTransactions)
|
if (!_isJournalingEnabled)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
rc = SynchronizeDirectory(WorkingDirectoryPath, CommittedDirectoryPath);
|
rc = SynchronizeDirectory(WorkingDirectoryPath, CommittedDirectoryPath);
|
||||||
@ -254,7 +261,8 @@ namespace LibHac.FsSystem
|
|||||||
if (StringUtils.GetLength(relativePath, PathTools.MaxPathLength + 1) > PathTools.MaxPathLength)
|
if (StringUtils.GetLength(relativePath, PathTools.MaxPathLength + 1) > PathTools.MaxPathLength)
|
||||||
return ResultFs.TooLongPath.Log();
|
return ResultFs.TooLongPath.Log();
|
||||||
|
|
||||||
U8Span workingPath = !_useTransactions && _isPersistentSaveData
|
// Use the committed directory directly if journaling is supported but not enabled
|
||||||
|
U8Span workingPath = _isJournalingSupported && !_isJournalingEnabled
|
||||||
? CommittedDirectoryPath
|
? CommittedDirectoryPath
|
||||||
: WorkingDirectoryPath;
|
: WorkingDirectoryPath;
|
||||||
|
|
||||||
@ -466,7 +474,7 @@ namespace LibHac.FsSystem
|
|||||||
{
|
{
|
||||||
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
|
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
|
||||||
|
|
||||||
if (!_useTransactions || !_isPersistentSaveData)
|
if (!_isJournalingEnabled || !_isJournalingSupported)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
if (_openWritableFileCount > 0)
|
if (_openWritableFileCount > 0)
|
||||||
@ -499,7 +507,7 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
protected override Result DoCommitProvisionally(long counter)
|
protected override Result DoCommitProvisionally(long counter)
|
||||||
{
|
{
|
||||||
if (!_canCommitProvisionally)
|
if (!_isMultiCommitSupported)
|
||||||
return ResultFs.UnsupportedCommitProvisionallyForDirectorySaveDataFileSystem.Log();
|
return ResultFs.UnsupportedCommitProvisionallyForDirectorySaveDataFileSystem.Log();
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
@ -507,11 +515,11 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
protected override Result DoRollback()
|
protected override Result DoRollback()
|
||||||
{
|
{
|
||||||
// No old data is kept for temporary save data, so there's nothing to rollback to
|
// No old data is kept for non-journaling save data, so there's nothing to rollback to
|
||||||
if (!_isPersistentSaveData)
|
if (!_isJournalingSupported)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
return Initialize(_isPersistentSaveData, _canCommitProvisionally, _useTransactions);
|
return Initialize(_isJournalingSupported, _isMultiCommitSupported, _isJournalingEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoGetFreeSpaceSize(out long freeSpace, U8Span path)
|
protected override Result DoGetFreeSpaceSize(out long freeSpace, U8Span path)
|
||||||
@ -589,7 +597,7 @@ namespace LibHac.FsSystem
|
|||||||
rc = _baseFs.CreateFile(WorkingExtraDataPath, Unsafe.SizeOf<SaveDataExtraData>());
|
rc = _baseFs.CreateFile(WorkingExtraDataPath, Unsafe.SizeOf<SaveDataExtraData>());
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (_isPersistentSaveData)
|
if (_isJournalingSupported)
|
||||||
{
|
{
|
||||||
rc = _baseFs.CreateFile(CommittedExtraDataPath, Unsafe.SizeOf<SaveDataExtraData>());
|
rc = _baseFs.CreateFile(CommittedExtraDataPath, Unsafe.SizeOf<SaveDataExtraData>());
|
||||||
if (rc.IsFailure() && !ResultFs.PathAlreadyExists.Includes(rc)) return rc;
|
if (rc.IsFailure() && !ResultFs.PathAlreadyExists.Includes(rc)) return rc;
|
||||||
@ -602,8 +610,8 @@ namespace LibHac.FsSystem
|
|||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only the working extra data is needed for temporary savedata
|
// Only the working extra data is needed for non-journaling savedata
|
||||||
if (!_isPersistentSaveData)
|
if (!_isJournalingSupported)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
rc = _baseFs.GetEntryType(out _, CommittedExtraDataPath);
|
rc = _baseFs.GetEntryType(out _, CommittedExtraDataPath);
|
||||||
@ -613,7 +621,7 @@ namespace LibHac.FsSystem
|
|||||||
rc = EnsureExtraDataSize(CommittedExtraDataPath);
|
rc = EnsureExtraDataSize(CommittedExtraDataPath);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (!_useTransactions)
|
if (!_isJournalingEnabled)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
return SynchronizeExtraData(WorkingExtraDataPath, CommittedExtraDataPath);
|
return SynchronizeExtraData(WorkingExtraDataPath, CommittedExtraDataPath);
|
||||||
@ -684,7 +692,7 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
private U8Span GetExtraDataPath()
|
private U8Span GetExtraDataPath()
|
||||||
{
|
{
|
||||||
return !_useTransactions && _isPersistentSaveData
|
return _isJournalingSupported && !_isJournalingEnabled
|
||||||
? CommittedExtraDataPath
|
? CommittedExtraDataPath
|
||||||
: WorkingExtraDataPath;
|
: WorkingExtraDataPath;
|
||||||
}
|
}
|
||||||
@ -757,7 +765,7 @@ namespace LibHac.FsSystem
|
|||||||
{
|
{
|
||||||
Assert.SdkRequires(_mutex.IsLockedByCurrentThread());
|
Assert.SdkRequires(_mutex.IsLockedByCurrentThread());
|
||||||
|
|
||||||
if (!_useTransactions || !_isPersistentSaveData)
|
if (!_isJournalingSupported || !_isJournalingEnabled)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
Result RenameCommittedFile() => _baseFs.RenameFile(CommittedExtraDataPath, SynchronizingExtraDataPath);
|
Result RenameCommittedFile() => _baseFs.RenameFile(CommittedExtraDataPath, SynchronizingExtraDataPath);
|
||||||
|
@ -7,36 +7,21 @@ namespace LibHac
|
|||||||
{
|
{
|
||||||
public static class HorizonFactory
|
public static class HorizonFactory
|
||||||
{
|
{
|
||||||
public static Horizon CreateWithFsConfig(HorizonConfiguration config, FileSystemServerConfig fsServerConfig)
|
public static Horizon CreateWithDefaultFsConfig(HorizonConfiguration config, IFileSystem rootFileSystem,
|
||||||
|
KeySet keySet)
|
||||||
{
|
{
|
||||||
var horizon = new Horizon(config);
|
var horizon = new Horizon(config);
|
||||||
|
|
||||||
HorizonClient fsServerClient = horizon.CreatePrivilegedHorizonClient();
|
HorizonClient fsServerClient = horizon.CreatePrivilegedHorizonClient();
|
||||||
var fsServer = new FileSystemServer(fsServerClient);
|
var fsServer = new FileSystemServer(fsServerClient);
|
||||||
|
|
||||||
FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, fsServerConfig);
|
var defaultObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(rootFileSystem, keySet, fsServer);
|
||||||
|
|
||||||
HorizonClient bcatServerClient = horizon.CreateHorizonClient();
|
|
||||||
_ = new BcatServer(bcatServerClient);
|
|
||||||
|
|
||||||
return horizon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Horizon CreateWithDefaultFsConfig(HorizonConfiguration config, IFileSystem rootFileSystem, KeySet keySet)
|
|
||||||
{
|
|
||||||
var horizon = new Horizon(config);
|
|
||||||
|
|
||||||
var defaultObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(rootFileSystem, keySet);
|
|
||||||
|
|
||||||
HorizonClient fsServerClient = horizon.CreatePrivilegedHorizonClient();
|
|
||||||
var fsServer = new FileSystemServer(fsServerClient);
|
|
||||||
|
|
||||||
var fsServerConfig = new FileSystemServerConfig
|
var fsServerConfig = new FileSystemServerConfig
|
||||||
{
|
{
|
||||||
DeviceOperator = defaultObjects.DeviceOperator,
|
DeviceOperator = defaultObjects.DeviceOperator,
|
||||||
ExternalKeySet = keySet.ExternalKeySet,
|
ExternalKeySet = keySet.ExternalKeySet,
|
||||||
FsCreators = defaultObjects.FsCreators,
|
FsCreators = defaultObjects.FsCreators,
|
||||||
KeySet = keySet
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, fsServerConfig);
|
FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, fsServerConfig);
|
||||||
|
@ -12,7 +12,12 @@ namespace LibHac.Tests.Fs.FileSystemClientTests
|
|||||||
rootFs = new InMemoryFileSystem();
|
rootFs = new InMemoryFileSystem();
|
||||||
var keySet = new KeySet();
|
var keySet = new KeySet();
|
||||||
|
|
||||||
var defaultObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(rootFs, keySet);
|
var horizon = new Horizon(new HorizonConfiguration());
|
||||||
|
|
||||||
|
HorizonClient fsServerClient = horizon.CreatePrivilegedHorizonClient();
|
||||||
|
var fsServer = new FileSystemServer(fsServerClient);
|
||||||
|
|
||||||
|
var defaultObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(rootFs, keySet, fsServer);
|
||||||
|
|
||||||
defaultObjects.SdCard.SetSdCardInsertionStatus(sdCardInserted);
|
defaultObjects.SdCard.SetSdCardInsertionStatus(sdCardInserted);
|
||||||
|
|
||||||
@ -20,9 +25,8 @@ namespace LibHac.Tests.Fs.FileSystemClientTests
|
|||||||
config.FsCreators = defaultObjects.FsCreators;
|
config.FsCreators = defaultObjects.FsCreators;
|
||||||
config.DeviceOperator = defaultObjects.DeviceOperator;
|
config.DeviceOperator = defaultObjects.DeviceOperator;
|
||||||
config.ExternalKeySet = new ExternalKeySet();
|
config.ExternalKeySet = new ExternalKeySet();
|
||||||
config.KeySet = keySet;
|
|
||||||
|
|
||||||
Horizon horizon = LibHac.HorizonFactory.CreateWithFsConfig(new HorizonConfiguration(), config);
|
FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, config);
|
||||||
|
|
||||||
HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient();
|
HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient();
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using LibHac.Common.Keys;
|
using LibHac.Bcat;
|
||||||
|
using LibHac.Common.Keys;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.FsSrv;
|
using LibHac.FsSrv;
|
||||||
@ -12,15 +13,22 @@ namespace LibHac.Tests
|
|||||||
IFileSystem rootFs = new InMemoryFileSystem();
|
IFileSystem rootFs = new InMemoryFileSystem();
|
||||||
var keySet = new KeySet();
|
var keySet = new KeySet();
|
||||||
|
|
||||||
var defaultObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(rootFs, keySet);
|
var horizon = new Horizon(new HorizonConfiguration());
|
||||||
|
|
||||||
|
HorizonClient fsServerClient = horizon.CreatePrivilegedHorizonClient();
|
||||||
|
var fsServer = new FileSystemServer(fsServerClient);
|
||||||
|
|
||||||
|
var defaultObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(rootFs, keySet, fsServer);
|
||||||
|
|
||||||
var config = new FileSystemServerConfig();
|
var config = new FileSystemServerConfig();
|
||||||
config.FsCreators = defaultObjects.FsCreators;
|
config.FsCreators = defaultObjects.FsCreators;
|
||||||
config.DeviceOperator = defaultObjects.DeviceOperator;
|
config.DeviceOperator = defaultObjects.DeviceOperator;
|
||||||
config.ExternalKeySet = new ExternalKeySet();
|
config.ExternalKeySet = new ExternalKeySet();
|
||||||
config.KeySet = keySet;
|
|
||||||
|
|
||||||
Horizon horizon = LibHac.HorizonFactory.CreateWithFsConfig(new HorizonConfiguration(), config);
|
FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, config);
|
||||||
|
|
||||||
|
HorizonClient bcatServerClient = horizon.CreateHorizonClient();
|
||||||
|
_ = new BcatServer(bcatServerClient);
|
||||||
|
|
||||||
return horizon;
|
return horizon;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user