mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Implement SaveDataFileSystemService functions
This commit is contained in:
parent
beca253086
commit
78e16d3d61
12 changed files with 981 additions and 188 deletions
11
src/LibHac/Fs/Save/InternalStorageFileNames.cs
Normal file
11
src/LibHac/Fs/Save/InternalStorageFileNames.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibHac.Fs.Save;
|
||||||
|
|
||||||
|
public static class InternalStorageFileNames
|
||||||
|
{
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameAllocationTableMeta => "AllocationTableMeta"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameRawSaveData => "RawSaveData"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameRawSaveDataWithZeroFree => "RawSaveDataWithZeroFree"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameSaveDataControlArea => "SaveDataControlArea"u8;
|
||||||
|
}
|
|
@ -1,11 +1,26 @@
|
||||||
using System;
|
using System;
|
||||||
|
using LibHac.Common;
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
namespace LibHac.FsSrv;
|
||||||
|
|
||||||
public delegate Result SaveTransferAesKeyGenerator(Span<byte> key,
|
public delegate Result SaveTransferAesKeyGenerator(Span<byte> outKeyBuffer,
|
||||||
SaveDataTransferCryptoConfiguration.KeyIndex index, ReadOnlySpan<byte> keySource, int keyGeneration);
|
SaveDataTransferCryptoConfiguration.KeyIndex index, ReadOnlySpan<byte> keySource, int keyGeneration);
|
||||||
|
|
||||||
public delegate Result SaveTransferCmacGenerator(Span<byte> mac, ReadOnlySpan<byte> data,
|
public delegate Result SaveTransferCmacGenerator(Span<byte> outMacBuffer, ReadOnlySpan<byte> data,
|
||||||
SaveDataTransferCryptoConfiguration.KeyIndex index, int keyGeneration);
|
SaveDataTransferCryptoConfiguration.Attributes attribute, SaveDataTransferCryptoConfiguration.KeyIndex index,
|
||||||
|
int keyGeneration);
|
||||||
|
|
||||||
|
public delegate Result SaveTransferOpenDecryptor(
|
||||||
|
ref SharedRef<SaveDataTransferCryptoConfiguration.IDecryptor> outDecryptor,
|
||||||
|
SaveDataTransferCryptoConfiguration.Attributes attribute, SaveDataTransferCryptoConfiguration.KeyIndex keyIndex,
|
||||||
|
ReadOnlySpan<byte> keySource, int keyGeneration, ReadOnlySpan<byte> iv, ReadOnlySpan<byte> mac);
|
||||||
|
|
||||||
|
public delegate Result SaveTransferOpenEncryptor(
|
||||||
|
ref SharedRef<SaveDataTransferCryptoConfiguration.IEncryptor> outEncryptor,
|
||||||
|
SaveDataTransferCryptoConfiguration.Attributes attribute, SaveDataTransferCryptoConfiguration.KeyIndex keyIndex,
|
||||||
|
ReadOnlySpan<byte> keySource, int keyGeneration, ReadOnlySpan<byte> iv);
|
||||||
|
|
||||||
|
public delegate bool VerifyRsaSignature(ReadOnlySpan<byte> signature, ReadOnlySpan<byte> modulus,
|
||||||
|
ReadOnlySpan<byte> exponent, ReadOnlySpan<byte> data);
|
||||||
|
|
||||||
public delegate Result PatrolAllocateCountGetter(out long successCount, out long failureCount);
|
public delegate Result PatrolAllocateCountGetter(out long successCount, out long failureCount);
|
|
@ -11,7 +11,7 @@ public interface ISaveDataTransferCoreInterface : IDisposable
|
||||||
{
|
{
|
||||||
Result GetFreeSpaceSizeForSaveData(out long outFreeSpaceSize, SaveDataSpaceId spaceId);
|
Result GetFreeSpaceSizeForSaveData(out long outFreeSpaceSize, SaveDataSpaceId spaceId);
|
||||||
Result QuerySaveDataTotalSize(out long outTotalSize, long dataSize, long journalSize);
|
Result QuerySaveDataTotalSize(out long outTotalSize, long dataSize, long journalSize);
|
||||||
Result CheckSaveDataFile(long saveDataId, SaveDataSpaceId spaceId);
|
Result CheckSaveDataFile(ulong 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, SaveDataAttribute attribute);
|
Result GetSaveDataInfo(out SaveDataInfo saveInfo, SaveDataSpaceId spaceId, SaveDataAttribute attribute);
|
||||||
Result ReadSaveDataFileSystemExtraDataCore(out SaveDataExtraData extraData, SaveDataSpaceId spaceId, ulong saveDataId, bool isTemporarySaveData);
|
Result ReadSaveDataFileSystemExtraDataCore(out SaveDataExtraData extraData, SaveDataSpaceId spaceId, ulong saveDataId, bool isTemporarySaveData);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class SaveDataMover : ISaveDataMover
|
||||||
private State _state;
|
private State _state;
|
||||||
private SdkMutex _mutex;
|
private SdkMutex _mutex;
|
||||||
|
|
||||||
public SaveDataMover(SharedRef<ISaveDataTransferCoreInterface> transferInterface, SaveDataSpaceId sourceSpaceId,
|
public SaveDataMover(in SharedRef<ISaveDataTransferCoreInterface> transferInterface, SaveDataSpaceId sourceSpaceId,
|
||||||
SaveDataSpaceId destinationSpaceId, NativeHandle transferMemoryHandle, ulong transferMemorySize)
|
SaveDataSpaceId destinationSpaceId, NativeHandle transferMemoryHandle, ulong transferMemorySize)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -113,8 +113,15 @@ public static class SaveDataProperties
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsObsoleteSystemSaveData(in SaveDataInfo info)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsWipingNeededAtCleanUp(in SaveDataInfo info)
|
public static bool IsWipingNeededAtCleanUp(in SaveDataInfo info)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ using IFile = LibHac.Fs.Fsa.IFile;
|
||||||
|
|
||||||
namespace LibHac.FsSrv.Impl;
|
namespace LibHac.FsSrv.Impl;
|
||||||
|
|
||||||
public class SaveDataTransferManager : IDisposable
|
public class SaveDataTransferManager : ISaveDataTransferManager
|
||||||
{
|
{
|
||||||
private SharedRef<ISaveDataTransferCoreInterface> _transferCoreInterface;
|
private SharedRef<ISaveDataTransferCoreInterface> _transferCoreInterface;
|
||||||
private SaveDataTransferCryptoConfiguration _cryptoConfig;
|
private SaveDataTransferCryptoConfiguration _cryptoConfig;
|
||||||
|
|
|
@ -182,13 +182,19 @@ public class SaveDataTransferManagerForSaveDataRepair<TPolicy> : ISaveDataTransf
|
||||||
private Optional<AesKey> _kek;
|
private Optional<AesKey> _kek;
|
||||||
private SaveDataTransferManagerForSaveDataRepair.KeyPackageV0.Content _keyPackage;
|
private SaveDataTransferManagerForSaveDataRepair.KeyPackageV0.Content _keyPackage;
|
||||||
private SaveDataPorterManager _porterManager;
|
private SaveDataPorterManager _porterManager;
|
||||||
private bool _canOpenTool;
|
private bool _canOpenPorterWithKey;
|
||||||
|
|
||||||
public SaveDataTransferManagerForSaveDataRepair(SaveDataTransferCryptoConfiguration cryptoConfig,
|
public SaveDataTransferManagerForSaveDataRepair(SaveDataTransferCryptoConfiguration cryptoConfig,
|
||||||
ref readonly SharedRef<ISaveDataTransferCoreInterface> coreInterface, SaveDataPorterManager porterManager,
|
ref readonly SharedRef<ISaveDataTransferCoreInterface> coreInterface, SaveDataPorterManager porterManager,
|
||||||
bool canOpenTool)
|
bool canOpenPorterWithKey)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_transferInterface = SharedRef<ISaveDataTransferCoreInterface>.CreateCopy(in coreInterface);
|
||||||
|
_cryptoConfig = cryptoConfig;
|
||||||
|
_isKeyPackageSet = false;
|
||||||
|
_kek = new Optional<AesKey>();
|
||||||
|
_porterManager = porterManager;
|
||||||
|
_canOpenPorterWithKey = canOpenPorterWithKey;
|
||||||
|
_cryptoConfig.GenerateRandomData(_challengeData.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#pragma warning disable CS0169 // Field is never used
|
#pragma warning disable CS0169 // Field is never used
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
using LibHac.Os;
|
using LibHac.Os;
|
||||||
|
|
||||||
namespace LibHac.FsSrv.Impl;
|
namespace LibHac.FsSrv.Impl;
|
||||||
|
@ -36,7 +37,7 @@ public abstract class Prohibitee : IDisposable
|
||||||
public abstract ApplicationId GetApplicationId();
|
public abstract ApplicationId GetApplicationId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SaveDataPorterProhibiter : IDisposable
|
public class SaveDataPorterProhibiter : ISaveDataTransferProhibiter
|
||||||
{
|
{
|
||||||
// IntrusiveList
|
// IntrusiveList
|
||||||
private SaveDataPorterManager _porterManager;
|
private SaveDataPorterManager _porterManager;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,10 +12,33 @@ using LibHac.FsSystem;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Os;
|
using LibHac.Os;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
|
using static LibHac.FsSrv.Anonymous;
|
||||||
using Utility = LibHac.FsSrv.Impl.Utility;
|
using Utility = LibHac.FsSrv.Impl.Utility;
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
namespace LibHac.FsSrv;
|
||||||
|
|
||||||
|
file static class Anonymous
|
||||||
|
{
|
||||||
|
public static bool IsDeviceUniqueMac(SaveDataSpaceId spaceId)
|
||||||
|
{
|
||||||
|
return spaceId == SaveDataSpaceId.System ||
|
||||||
|
spaceId == SaveDataSpaceId.User ||
|
||||||
|
spaceId == SaveDataSpaceId.Temporary ||
|
||||||
|
spaceId == SaveDataSpaceId.ProperSystem ||
|
||||||
|
spaceId == SaveDataSpaceId.SafeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result WipeData(IFileSystem fileSystem, ref readonly Path filePath, RandomDataGenerator random)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result WipeMasterHeader(IFileSystem fileSystem, ref readonly Path filePath, RandomDataGenerator random)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the lower-level operations on save data.
|
/// Handles the lower-level operations on save data.
|
||||||
/// <see cref="SaveDataFileSystemService"/> uses this class to provide save data APIs at a higher level of abstraction.
|
/// <see cref="SaveDataFileSystemService"/> uses this class to provide save data APIs at a higher level of abstraction.
|
||||||
|
@ -30,8 +53,10 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
|
|
||||||
private SaveDataFileSystemCacheManager _saveFileSystemCacheManager;
|
private SaveDataFileSystemCacheManager _saveFileSystemCacheManager;
|
||||||
private SaveDataExtraDataAccessorCacheManager _saveExtraDataCacheManager;
|
private SaveDataExtraDataAccessorCacheManager _saveExtraDataCacheManager;
|
||||||
// Save data porter manager
|
private SaveDataPorterManager _saveDataPorterManager;
|
||||||
private bool _isSdCardAccessible;
|
private bool _isSdCardAccessible;
|
||||||
|
private Optional<uint> _integritySaveDataVersion;
|
||||||
|
private Optional<uint> _journalIntegritySaveDataVersion;
|
||||||
private TimeStampGetter _timeStampGetter;
|
private TimeStampGetter _timeStampGetter;
|
||||||
|
|
||||||
internal HorizonClient Hos => _config.FsServer.Hos;
|
internal HorizonClient Hos => _config.FsServer.Hos;
|
||||||
|
@ -69,29 +94,17 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
public ISaveDataIndexerManager SaveIndexerManager;
|
public ISaveDataIndexerManager SaveIndexerManager;
|
||||||
public DebugConfigurationServiceImpl DebugConfigService;
|
public DebugConfigurationServiceImpl DebugConfigService;
|
||||||
|
|
||||||
|
public uint JournalIntegritySaveDataVersion;
|
||||||
|
public uint JournalIntegritySupportedVersionMin;
|
||||||
|
public uint JournalIntegritySupportedVersionMax;
|
||||||
|
public uint IntegritySaveDataVersion;
|
||||||
|
public uint IntegritySupportedVersionMin;
|
||||||
|
public uint IntegritySupportedVersionMax;
|
||||||
|
|
||||||
// LibHac additions
|
// LibHac additions
|
||||||
public FileSystemServer FsServer;
|
public FileSystemServer FsServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsDeviceUniqueMac(SaveDataSpaceId spaceId)
|
|
||||||
{
|
|
||||||
return spaceId == SaveDataSpaceId.System ||
|
|
||||||
spaceId == SaveDataSpaceId.User ||
|
|
||||||
spaceId == SaveDataSpaceId.Temporary ||
|
|
||||||
spaceId == SaveDataSpaceId.ProperSystem ||
|
|
||||||
spaceId == SaveDataSpaceId.SafeMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Result WipeData(IFileSystem fileSystem, ref readonly Path filePath, RandomDataGenerator random)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Result WipeMasterHeader(IFileSystem fileSystem, ref readonly Path filePath, RandomDataGenerator random)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaveDataFileSystemServiceImpl(in Configuration configuration)
|
public SaveDataFileSystemServiceImpl(in Configuration configuration)
|
||||||
{
|
{
|
||||||
_config = configuration;
|
_config = configuration;
|
||||||
|
@ -115,6 +128,32 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
return _config.DebugConfigService;
|
return _config.DebugConfigService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetIntegritySaveDataVersion(uint version)
|
||||||
|
{
|
||||||
|
_integritySaveDataVersion.Set(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetJournalIntegritySaveDataVersion(uint version)
|
||||||
|
{
|
||||||
|
_journalIntegritySaveDataVersion.Set(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetIntegritySaveDataVersion()
|
||||||
|
{
|
||||||
|
if (_integritySaveDataVersion.HasValue)
|
||||||
|
return _integritySaveDataVersion.Value;
|
||||||
|
|
||||||
|
return _config.IntegritySaveDataVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetJournalIntegritySaveDataVersion()
|
||||||
|
{
|
||||||
|
if (_journalIntegritySaveDataVersion.HasValue)
|
||||||
|
return _journalIntegritySaveDataVersion.Value;
|
||||||
|
|
||||||
|
return _config.JournalIntegritySaveDataVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public Result DoesSaveDataEntityExist(out bool exists, SaveDataSpaceId spaceId, ulong saveDataId)
|
public Result DoesSaveDataEntityExist(out bool exists, SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
{
|
{
|
||||||
UnsafeHelpers.SkipParamInit(out exists);
|
UnsafeHelpers.SkipParamInit(out exists);
|
||||||
|
@ -149,6 +188,11 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result GetSaveDataCommitTimeStamp(out long timeStamp)
|
||||||
|
{
|
||||||
|
return _config.TimeService.GetCurrentPosixTime(out timeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataFile(ref SharedRef<IFile> outFile, SaveDataSpaceId spaceId, ulong saveDataId,
|
public Result OpenSaveDataFile(ref SharedRef<IFile> outFile, SaveDataSpaceId spaceId, ulong saveDataId,
|
||||||
OpenMode openMode)
|
OpenMode openMode)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +281,7 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
saveDataMetaIdDirectoryNameBuffer, saveDataId);
|
saveDataMetaIdDirectoryNameBuffer, saveDataId);
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
return OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, in saveDataMetaIdDirectoryName).Ret();
|
return OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, saveDataId, in saveDataMetaIdDirectoryName).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataInternalStorageFileSystem(ref SharedRef<IFileSystem> outFileSystem,
|
public Result OpenSaveDataInternalStorageFileSystem(ref SharedRef<IFileSystem> outFileSystem,
|
||||||
|
@ -253,8 +297,8 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result ExtendSaveDataFileSystemCore(out long extendedTotalSize, ulong saveDataId, SaveDataSpaceId spaceId,
|
private Result OpenSaveDataExtensionContextFile(ref UniqueRef<IFile> outFile, IFile saveDataFile, ulong saveDataId,
|
||||||
SaveDataType type, long dataSize, long journalSize, ref readonly Path saveDataRootPath, bool isExtensionStart)
|
SaveDataSpaceId spaceId, long dataSize, long journalSize, bool createIfMissing, bool isReconstructible)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -273,6 +317,12 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
journalSize: 0, in saveDataRootPath, isExtensionStart: false);
|
journalSize: 0, in saveDataRootPath, isExtensionStart: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result ExtendSaveDataFileSystemCore(out long extendedTotalSize, ulong saveDataId, SaveDataSpaceId spaceId,
|
||||||
|
SaveDataType type, long dataSize, long journalSize, ref readonly Path saveDataRootPath, bool isExtensionStart)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Result FinishExtendSaveDataFileSystem(ulong saveDataId, SaveDataSpaceId spaceId)
|
public Result FinishExtendSaveDataFileSystem(ulong saveDataId, SaveDataSpaceId spaceId)
|
||||||
{
|
{
|
||||||
Result res = DeleteSaveDataMeta(saveDataId, spaceId, SaveDataMetaType.ExtensionContext);
|
Result res = DeleteSaveDataMeta(saveDataId, spaceId, SaveDataMetaType.ExtensionContext);
|
||||||
|
@ -296,13 +346,6 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
FinishExtendSaveDataFileSystem(saveDataId, spaceId).IgnoreResult();
|
FinishExtendSaveDataFileSystem(saveDataId, spaceId).IgnoreResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result QuerySaveDataTotalSize(out long totalSize, int blockSize, long dataSize, long journalSize)
|
|
||||||
{
|
|
||||||
// Todo: Implement
|
|
||||||
totalSize = 0;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result CreateSaveDataMeta(ulong saveDataId, SaveDataSpaceId spaceId, SaveDataMetaType metaType,
|
public Result CreateSaveDataMeta(ulong saveDataId, SaveDataSpaceId spaceId, SaveDataMetaType metaType,
|
||||||
long metaFileSize)
|
long metaFileSize)
|
||||||
{
|
{
|
||||||
|
@ -356,8 +399,7 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
Result res = PathFunctions.SetUpFixedPath(ref saveDataMetaDirectoryName.Ref(), metaDirName);
|
Result res = PathFunctions.SetUpFixedPath(ref saveDataMetaDirectoryName.Ref(), metaDirName);
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
res = OpenSaveDataDirectoryFileSystemImpl(ref fileSystem.Ref, spaceId, in saveDataMetaDirectoryName,
|
res = OpenSaveDataDirectoryFileSystemImpl(ref fileSystem.Ref, spaceId, saveDataId, in saveDataMetaDirectoryName, createIfMissing: false);
|
||||||
createIfMissing: false);
|
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
using scoped var saveDataIdDirectoryName = new Path();
|
using scoped var saveDataIdDirectoryName = new Path();
|
||||||
|
@ -400,6 +442,13 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result QuerySaveDataTotalSize(out long totalSize, long blockSize, long dataSize, long journalSize)
|
||||||
|
{
|
||||||
|
// Todo: Implement
|
||||||
|
totalSize = 0;
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
public Result CreateSaveDataFileSystem(ulong saveDataId, in SaveDataCreationInfo2 creationInfo,
|
public Result CreateSaveDataFileSystem(ulong saveDataId, in SaveDataCreationInfo2 creationInfo,
|
||||||
ref readonly Path saveDataRootPath, bool skipFormat)
|
ref readonly Path saveDataRootPath, bool skipFormat)
|
||||||
{
|
{
|
||||||
|
@ -631,9 +680,14 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result GetSaveDataCommitTimeStamp(out long timeStamp)
|
public Result RecoverSaveDataFileSystemMasterHeader(SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
{
|
{
|
||||||
return _config.TimeService.GetCurrentPosixTime(out timeStamp);
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result UpdateSaveDataFileSystemMac(SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSaveEmulated(ref readonly Path saveDataRootPath)
|
private bool IsSaveEmulated(ref readonly Path saveDataRootPath)
|
||||||
|
@ -641,10 +695,10 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
return !saveDataRootPath.IsEmpty();
|
return !saveDataRootPath.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataDirectoryFileSystem(ref SharedRef<IFileSystem> outFileSystem,
|
public Result OpenSaveDataDirectoryFileSystem(ref SharedRef<IFileSystem> outFileSystem, SaveDataSpaceId spaceId,
|
||||||
SaveDataSpaceId spaceId, ulong saveDataId)
|
ulong saveDataId)
|
||||||
{
|
{
|
||||||
using scoped var rootPath = new Path();
|
using var rootPath = new Path();
|
||||||
|
|
||||||
return OpenSaveDataDirectoryFileSystem(ref outFileSystem, spaceId, saveDataId, in rootPath, allowEmulatedSave: true);
|
return OpenSaveDataDirectoryFileSystem(ref outFileSystem, spaceId, saveDataId, in rootPath, allowEmulatedSave: true);
|
||||||
}
|
}
|
||||||
|
@ -703,20 +757,14 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
res = PathFunctions.SetUpFixedPath(ref saveDataAreaDirectoryName.Ref(), saveDirName);
|
res = PathFunctions.SetUpFixedPath(ref saveDataAreaDirectoryName.Ref(), saveDirName);
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
res = OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, in saveDataAreaDirectoryName);
|
res = OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, saveDataId, in saveDataAreaDirectoryName);
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem,
|
private Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem, SaveDataSpaceId spaceId,
|
||||||
SaveDataSpaceId spaceId, ref readonly Path directoryPath)
|
ulong saveDataId, ref readonly Path directoryPath, bool createIfMissing)
|
||||||
{
|
|
||||||
return OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, in directoryPath, createIfMissing: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem,
|
|
||||||
SaveDataSpaceId spaceId, ref readonly Path directoryPath, bool createIfMissing)
|
|
||||||
{
|
{
|
||||||
using var baseFileSystem = new SharedRef<IFileSystem>();
|
using var baseFileSystem = new SharedRef<IFileSystem>();
|
||||||
|
|
||||||
|
@ -812,6 +860,12 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result OpenSaveDataDirectoryFileSystemImpl(ref SharedRef<IFileSystem> outFileSystem, SaveDataSpaceId spaceId,
|
||||||
|
ulong saveDataId, ref readonly Path directoryPath)
|
||||||
|
{
|
||||||
|
return OpenSaveDataDirectoryFileSystemImpl(ref outFileSystem, spaceId, saveDataId, in directoryPath, createIfMissing: true);
|
||||||
|
}
|
||||||
|
|
||||||
public Result IsProvisionallyCommittedSaveData(out bool isProvisionallyCommitted, in SaveDataInfo saveInfo)
|
public Result IsProvisionallyCommittedSaveData(out bool isProvisionallyCommitted, in SaveDataInfo saveInfo)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
@ -881,6 +935,11 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SaveDataPorterManager GetSaveDataPorterManager()
|
||||||
|
{
|
||||||
|
return _saveDataPorterManager;
|
||||||
|
}
|
||||||
|
|
||||||
public Result GetSaveDataIndexCount(out int count)
|
public Result GetSaveDataIndexCount(out int count)
|
||||||
{
|
{
|
||||||
UnsafeHelpers.SkipParamInit(out count);
|
UnsafeHelpers.SkipParamInit(out count);
|
||||||
|
|
|
@ -17,9 +17,13 @@ public class SaveDataTransferCryptoConfiguration
|
||||||
public Span<byte> KekEncryptionKeyModulus => _kekEncryptionKeyModulus;
|
public Span<byte> KekEncryptionKeyModulus => _kekEncryptionKeyModulus;
|
||||||
public Span<byte> KeyPackageSigningModulus => _keyPackageSigningModulus;
|
public Span<byte> KeyPackageSigningModulus => _keyPackageSigningModulus;
|
||||||
|
|
||||||
public SaveTransferAesKeyGenerator GenerateAesKey { get; set; }
|
|
||||||
public RandomDataGenerator GenerateRandomData { get; set; }
|
public RandomDataGenerator GenerateRandomData { get; set; }
|
||||||
public SaveTransferCmacGenerator GenerateCmac { get; set; }
|
public SaveTransferCmacGenerator GenerateCmac { get; set; }
|
||||||
|
public SaveTransferOpenDecryptor OpenDecryptor { get; set; }
|
||||||
|
public SaveTransferOpenEncryptor OpenEncryptor { get; set; }
|
||||||
|
public VerifyRsaSignature VerifySignature { get; set; }
|
||||||
|
public Action ResetConfiguration { get; set; }
|
||||||
|
public SaveTransferAesKeyGenerator GenerateAesKey { get; set; }
|
||||||
|
|
||||||
public enum KeyIndex
|
public enum KeyIndex
|
||||||
{
|
{
|
||||||
|
@ -34,7 +38,10 @@ public class SaveDataTransferCryptoConfiguration
|
||||||
SaveDataRepairInitialDataMacAfterRepair
|
SaveDataRepairInitialDataMacAfterRepair
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Attributes { }
|
public enum Attributes
|
||||||
|
{
|
||||||
|
Default = 0
|
||||||
|
}
|
||||||
|
|
||||||
public interface IEncryptor : IDisposable
|
public interface IEncryptor : IDisposable
|
||||||
{
|
{
|
||||||
|
|
18
src/LibHac/FsSystem/Save/InternalStorageFileNames.cs
Normal file
18
src/LibHac/FsSystem/Save/InternalStorageFileNames.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibHac.FsSystem.Save;
|
||||||
|
|
||||||
|
public static class InternalStorageFileNames
|
||||||
|
{
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegrity => "InternalStorageFileNameIntegrity"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegrityExtraData => "InternalStorageFileNameIntegrityExtraData"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegrityHashAlgorithm => "InternalStorageFileNameHashAlgorithm"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegritySeed => "InternalStorageFileNameIntegritySeed"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegritySeedEnabled => "InternalStorageFileNameIntegrity"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegritySha2Salt => "InternalStorageFileNameIntegritySha2Salt"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegritySha2SaltWithZeroFree => "InternalStorageFileNameIntegritySha2SaltWithZeroFree"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameIntegrityWithZeroFree => "InternalStorageFileNameIntegrityWithZeroFree"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameJournal => "InternalStorageFileNameJournal"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameMasterHeaderMac => "MasterHeaderMac"u8;
|
||||||
|
public static ReadOnlySpan<byte> InternalStorageFileNameSha2Salt => "InternalStorageFileNameSha2Salt"u8;
|
||||||
|
}
|
Loading…
Reference in a new issue