mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add BaseStorageService
This commit is contained in:
parent
c29fed67c1
commit
6b6a31dcea
15 changed files with 370 additions and 114 deletions
|
@ -190,4 +190,11 @@ namespace LibHac.Fs
|
||||||
None = 0,
|
None = 0,
|
||||||
PseudoCaseSensitive = 1
|
PseudoCaseSensitive = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SimulatingDeviceDetectionMode
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Inserted = 1,
|
||||||
|
NotInserted = 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
238
src/LibHac/FsSrv/BaseStorageService.cs
Normal file
238
src/LibHac/FsSrv/BaseStorageService.cs
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using LibHac.Fs;
|
||||||
|
using LibHac.FsSrv.Creators;
|
||||||
|
using LibHac.FsSrv.Impl;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
|
using LibHac.FsSystem;
|
||||||
|
|
||||||
|
namespace LibHac.FsSrv
|
||||||
|
{
|
||||||
|
public readonly struct BaseStorageService
|
||||||
|
{
|
||||||
|
private readonly BaseStorageServiceImpl _serviceImpl;
|
||||||
|
private readonly ulong _processId;
|
||||||
|
|
||||||
|
public BaseStorageService(BaseStorageServiceImpl serviceImpl, ulong processId)
|
||||||
|
{
|
||||||
|
_serviceImpl = serviceImpl;
|
||||||
|
_processId = processId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, BisPartitionId id)
|
||||||
|
{
|
||||||
|
storage = default;
|
||||||
|
|
||||||
|
var storageFlag = StorageType.Bis;
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(storageFlag);
|
||||||
|
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
rc = GetAccessibilityForOpenBisPartition(out Accessibility accessibility, programInfo, id);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
bool canAccess = accessibility.CanRead && accessibility.CanWrite;
|
||||||
|
|
||||||
|
if (!canAccess)
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
ReferenceCountedDisposable<IStorage> tempStorage = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rc = _serviceImpl.OpenBisStorage(out tempStorage, id);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
tempStorage = StorageLayoutTypeSetStorage.CreateShared(ref tempStorage, storageFlag);
|
||||||
|
|
||||||
|
// Todo: Async storage
|
||||||
|
|
||||||
|
storage = StorageInterfaceAdapter.CreateShared(ref tempStorage);
|
||||||
|
return Result.Success;
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
tempStorage?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result InvalidateBisCache()
|
||||||
|
{
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
if (!programInfo.AccessControl.CanCall(OperationType.InvalidateBisCache))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
return _serviceImpl.InvalidateBisCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
||||||
|
GameCardPartitionRaw partitionId)
|
||||||
|
{
|
||||||
|
storage = default;
|
||||||
|
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
Accessibility accessibility =
|
||||||
|
programInfo.AccessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||||
|
|
||||||
|
bool canAccess = accessibility.CanRead && accessibility.CanWrite;
|
||||||
|
|
||||||
|
if (!canAccess)
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
ReferenceCountedDisposable<IStorage> tempStorage = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rc = _serviceImpl.OpenGameCardPartition(out tempStorage, handle, partitionId);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
// Todo: Async storage
|
||||||
|
|
||||||
|
storage = StorageInterfaceAdapter.CreateShared(ref tempStorage);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
tempStorage?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||||
|
{
|
||||||
|
deviceOperator = _serviceImpl.Config.DeviceOperator.AddReference();
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
|
{
|
||||||
|
eventNotifier = default;
|
||||||
|
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
if (!programInfo.AccessControl.CanCall(OperationType.OpenSdCardDetectionEventNotifier))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
|
{
|
||||||
|
eventNotifier = default;
|
||||||
|
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
if (!programInfo.AccessControl.CanCall(OperationType.OpenGameCardDetectionEventNotifier))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result SimulateDeviceDetectionEvent(SdmmcPort port, SimulatingDeviceDetectionMode mode, bool signalEvent)
|
||||||
|
{
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
if (!programInfo.AccessControl.CanCall(OperationType.SimulateDevice))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result GetProgramInfo(out ProgramInfo programInfo)
|
||||||
|
{
|
||||||
|
return _serviceImpl.GetProgramInfo(out programInfo, _processId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result GetAccessibilityForOpenBisPartition(out Accessibility accessibility, ProgramInfo programInfo,
|
||||||
|
BisPartitionId partitionId)
|
||||||
|
{
|
||||||
|
Unsafe.SkipInit(out accessibility);
|
||||||
|
|
||||||
|
AccessibilityType type = partitionId switch
|
||||||
|
{
|
||||||
|
BisPartitionId.BootPartition1Root => AccessibilityType.OpenBisPartitionBootPartition1Root,
|
||||||
|
BisPartitionId.BootPartition2Root => AccessibilityType.OpenBisPartitionBootPartition2Root,
|
||||||
|
BisPartitionId.UserDataRoot => AccessibilityType.OpenBisPartitionUserDataRoot,
|
||||||
|
BisPartitionId.BootConfigAndPackage2Part1 => AccessibilityType.OpenBisPartitionBootConfigAndPackage2Part1,
|
||||||
|
BisPartitionId.BootConfigAndPackage2Part2 => AccessibilityType.OpenBisPartitionBootConfigAndPackage2Part2,
|
||||||
|
BisPartitionId.BootConfigAndPackage2Part3 => AccessibilityType.OpenBisPartitionBootConfigAndPackage2Part3,
|
||||||
|
BisPartitionId.BootConfigAndPackage2Part4 => AccessibilityType.OpenBisPartitionBootConfigAndPackage2Part4,
|
||||||
|
BisPartitionId.BootConfigAndPackage2Part5 => AccessibilityType.OpenBisPartitionBootConfigAndPackage2Part5,
|
||||||
|
BisPartitionId.BootConfigAndPackage2Part6 => AccessibilityType.OpenBisPartitionBootConfigAndPackage2Part6,
|
||||||
|
BisPartitionId.CalibrationBinary => AccessibilityType.OpenBisPartitionCalibrationBinary,
|
||||||
|
BisPartitionId.CalibrationFile => AccessibilityType.OpenBisPartitionCalibrationFile,
|
||||||
|
BisPartitionId.SafeMode => AccessibilityType.OpenBisPartitionSafeMode,
|
||||||
|
BisPartitionId.User => AccessibilityType.OpenBisPartitionUser,
|
||||||
|
BisPartitionId.System => AccessibilityType.OpenBisPartitionSystem,
|
||||||
|
BisPartitionId.SystemProperEncryption => AccessibilityType.OpenBisPartitionSystemProperEncryption,
|
||||||
|
BisPartitionId.SystemProperPartition => AccessibilityType.OpenBisPartitionSystemProperPartition,
|
||||||
|
_ => (AccessibilityType)(-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (type == (AccessibilityType)(-1))
|
||||||
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
|
||||||
|
accessibility = programInfo.AccessControl.GetAccessibilityFor(type);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BaseStorageServiceImpl
|
||||||
|
{
|
||||||
|
internal Configuration Config;
|
||||||
|
|
||||||
|
public BaseStorageServiceImpl(in Configuration configuration)
|
||||||
|
{
|
||||||
|
Config = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Configuration
|
||||||
|
{
|
||||||
|
public IBuiltInStorageCreator BisStorageCreator;
|
||||||
|
public IGameCardStorageCreator GameCardStorageCreator;
|
||||||
|
|
||||||
|
// LibHac additions
|
||||||
|
public ProgramRegistryImpl ProgramRegistry;
|
||||||
|
// Todo: The DeviceOperator in FS uses mostly global state. Decide how to handle this.
|
||||||
|
public ReferenceCountedDisposable<IDeviceOperator> DeviceOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenBisStorage(out ReferenceCountedDisposable<IStorage> storage, BisPartitionId partitionId)
|
||||||
|
{
|
||||||
|
return Config.BisStorageCreator.Create(out storage, partitionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result InvalidateBisCache()
|
||||||
|
{
|
||||||
|
return Config.BisStorageCreator.InvalidateCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenGameCardPartition(out ReferenceCountedDisposable<IStorage> storage, GameCardHandle handle,
|
||||||
|
GameCardPartitionRaw partitionId)
|
||||||
|
{
|
||||||
|
switch (partitionId)
|
||||||
|
{
|
||||||
|
case GameCardPartitionRaw.NormalReadOnly:
|
||||||
|
return Config.GameCardStorageCreator.CreateReadOnly(handle, out storage);
|
||||||
|
case GameCardPartitionRaw.SecureReadOnly:
|
||||||
|
return Config.GameCardStorageCreator.CreateSecureReadOnly(handle, out storage);
|
||||||
|
case GameCardPartitionRaw.RootWriteOnly:
|
||||||
|
return Config.GameCardStorageCreator.CreateWriteOnly(handle, out storage);
|
||||||
|
default:
|
||||||
|
storage = default;
|
||||||
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||||
|
{
|
||||||
|
return Config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ namespace LibHac.FsSrv.Creators
|
||||||
GameCard = gameCard;
|
GameCard = gameCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result CreateNormal(GameCardHandle handle, out IStorage storage)
|
public Result CreateReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage)
|
||||||
{
|
{
|
||||||
storage = default;
|
storage = default;
|
||||||
|
|
||||||
|
@ -21,16 +21,17 @@ namespace LibHac.FsSrv.Creators
|
||||||
return ResultFs.InvalidGameCardHandleOnOpenNormalPartition.Log();
|
return ResultFs.InvalidGameCardHandleOnOpenNormalPartition.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseStorage = new ReadOnlyGameCardStorage(GameCard, handle);
|
var baseStorage = new ReferenceCountedDisposable<IStorage>(new ReadOnlyGameCardStorage(GameCard, handle));
|
||||||
|
|
||||||
Result rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
Result rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
storage = new SubStorage(baseStorage, 0, cardInfo.SecureAreaOffset);
|
storage = new ReferenceCountedDisposable<IStorage>(
|
||||||
|
new SubStorage(baseStorage, 0, cardInfo.SecureAreaOffset));
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result CreateSecure(GameCardHandle handle, out IStorage storage)
|
public Result CreateSecureReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage)
|
||||||
{
|
{
|
||||||
storage = default;
|
storage = default;
|
||||||
|
|
||||||
|
@ -48,16 +49,19 @@ namespace LibHac.FsSrv.Creators
|
||||||
rc = GameCard.GetGameCardImageHash(imageHash);
|
rc = GameCard.GetGameCardImageHash(imageHash);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
var baseStorage = new ReadOnlyGameCardStorage(GameCard, handle, deviceId, imageHash);
|
var baseStorage =
|
||||||
|
new ReferenceCountedDisposable<IStorage>(new ReadOnlyGameCardStorage(GameCard, handle, deviceId,
|
||||||
|
imageHash));
|
||||||
|
|
||||||
rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
storage = new SubStorage(baseStorage, cardInfo.SecureAreaOffset, cardInfo.SecureAreaSize);
|
storage = new ReferenceCountedDisposable<IStorage>(new SubStorage(baseStorage, cardInfo.SecureAreaOffset,
|
||||||
|
cardInfo.SecureAreaSize));
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result CreateWritable(GameCardHandle handle, out IStorage storage)
|
public Result CreateWriteOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace LibHac.FsSrv.Creators
|
||||||
{
|
{
|
||||||
public interface IBuiltInStorageCreator
|
public interface IBuiltInStorageCreator
|
||||||
{
|
{
|
||||||
Result Create(out IStorage storage, BisPartitionId partitionId);
|
Result Create(out ReferenceCountedDisposable<IStorage> storage, BisPartitionId partitionId);
|
||||||
|
Result InvalidateCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ namespace LibHac.FsSrv.Creators
|
||||||
{
|
{
|
||||||
public interface IGameCardStorageCreator
|
public interface IGameCardStorageCreator
|
||||||
{
|
{
|
||||||
Result CreateNormal(GameCardHandle handle, out IStorage storage);
|
Result CreateReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage);
|
||||||
Result CreateSecure(GameCardHandle handle, out IStorage storage);
|
Result CreateSecureReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage);
|
||||||
Result CreateWritable(GameCardHandle handle, out IStorage storage);
|
Result CreateWriteOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using LibHac.Common.Keys;
|
using LibHac.Common.Keys;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.FsSrv.Creators;
|
using LibHac.FsSrv.Creators;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace LibHac.FsSrv
|
||||||
public class FileSystemProxyConfiguration
|
public class FileSystemProxyConfiguration
|
||||||
{
|
{
|
||||||
public FileSystemCreators FsCreatorInterfaces { get; set; }
|
public FileSystemCreators FsCreatorInterfaces { get; set; }
|
||||||
|
public BaseStorageServiceImpl BaseStorageService { get; set; }
|
||||||
public BaseFileSystemServiceImpl BaseFileSystemService { get; set; }
|
public BaseFileSystemServiceImpl BaseFileSystemService { get; set; }
|
||||||
public NcaFileSystemServiceImpl NcaFileSystemService { get; set; }
|
public NcaFileSystemServiceImpl NcaFileSystemService { get; set; }
|
||||||
public SaveDataFileSystemServiceImpl SaveDataFileSystemService { get; set; }
|
public SaveDataFileSystemServiceImpl SaveDataFileSystemService { get; set; }
|
||||||
|
|
|
@ -4,8 +4,6 @@ using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.Fs.Shim;
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSrv.Creators;
|
using LibHac.FsSrv.Creators;
|
||||||
using LibHac.FsSrv.Impl;
|
|
||||||
using LibHac.FsSrv.Sf;
|
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
|
@ -15,67 +13,14 @@ namespace LibHac.FsSrv
|
||||||
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
||||||
internal ProgramRegistryImpl ProgramRegistry { get; }
|
internal ProgramRegistryImpl ProgramRegistry { get; }
|
||||||
|
|
||||||
private ReferenceCountedDisposable<IDeviceOperator> DeviceOperator { get; }
|
|
||||||
|
|
||||||
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
||||||
|
|
||||||
private const string NintendoDirectoryName = "Nintendo";
|
private const string NintendoDirectoryName = "Nintendo";
|
||||||
|
|
||||||
private GlobalAccessLogMode LogMode { get; set; }
|
public FileSystemProxyCoreImpl(FileSystemProxyConfiguration config)
|
||||||
|
|
||||||
internal ISaveDataIndexerManager SaveDataIndexerManager { get; private set; }
|
|
||||||
|
|
||||||
public FileSystemProxyCoreImpl(FileSystemProxyConfiguration config, IDeviceOperator deviceOperator)
|
|
||||||
{
|
{
|
||||||
Config = config;
|
Config = config;
|
||||||
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
||||||
DeviceOperator = new ReferenceCountedDisposable<IDeviceOperator>(deviceOperator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
|
||||||
GameCardPartitionRaw partitionId)
|
|
||||||
{
|
|
||||||
storage = default;
|
|
||||||
|
|
||||||
Result rc;
|
|
||||||
IStorage gcStorage = null;
|
|
||||||
ReferenceCountedDisposable<IStorage> sharedGcStorage = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (partitionId)
|
|
||||||
{
|
|
||||||
case GameCardPartitionRaw.NormalReadOnly:
|
|
||||||
rc = FsCreators.GameCardStorageCreator.CreateNormal(handle, out gcStorage);
|
|
||||||
break;
|
|
||||||
case GameCardPartitionRaw.SecureReadOnly:
|
|
||||||
rc = FsCreators.GameCardStorageCreator.CreateSecure(handle, out gcStorage);
|
|
||||||
break;
|
|
||||||
case GameCardPartitionRaw.RootWriteOnly:
|
|
||||||
rc = FsCreators.GameCardStorageCreator.CreateWritable(handle, out gcStorage);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(partitionId), partitionId, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
sharedGcStorage = new ReferenceCountedDisposable<IStorage>(gcStorage);
|
|
||||||
gcStorage = null;
|
|
||||||
|
|
||||||
storage = StorageInterfaceAdapter.CreateShared(ref sharedGcStorage);
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
gcStorage?.Dispose();
|
|
||||||
sharedGcStorage?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
|
||||||
{
|
|
||||||
deviceOperator = DeviceOperator.AddReference();
|
|
||||||
return Result.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
|
@ -177,29 +122,7 @@ namespace LibHac.FsSrv
|
||||||
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
||||||
{
|
{
|
||||||
seed.Value.CopyTo(SdEncryptionSeed);
|
seed.Value.CopyTo(SdEncryptionSeed);
|
||||||
// todo: FsCreators.SaveDataFileSystemCreator.SetSdCardEncryptionSeed(seed);
|
|
||||||
|
|
||||||
SaveDataIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdSystem);
|
|
||||||
SaveDataIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdCache);
|
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result SetGlobalAccessLogMode(GlobalAccessLogMode mode)
|
|
||||||
{
|
|
||||||
LogMode = mode;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode)
|
|
||||||
{
|
|
||||||
mode = LogMode;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SetSaveDataIndexerManager(ISaveDataIndexerManager manager)
|
|
||||||
{
|
|
||||||
SaveDataIndexerManager = manager;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,12 +386,12 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
public Result OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, BisPartitionId partitionId)
|
public Result OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, BisPartitionId partitionId)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return GetBaseStorageService().OpenBisStorage(out storage, partitionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result InvalidateBisCache()
|
public Result InvalidateBisCache()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return GetBaseStorageService().InvalidateBisCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path)
|
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path)
|
||||||
|
@ -457,26 +457,27 @@ namespace LibHac.FsSrv
|
||||||
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
||||||
GameCardPartitionRaw partitionId)
|
GameCardPartitionRaw partitionId)
|
||||||
{
|
{
|
||||||
// Missing permission check and StorageInterfaceAdapter
|
return GetBaseStorageService().OpenGameCardStorage(out storage, handle, partitionId);
|
||||||
|
|
||||||
return FsProxyCore.OpenGameCardStorage(out storage, handle, partitionId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||||
{
|
{
|
||||||
// Missing permission check
|
return GetBaseStorageService().OpenDeviceOperator(out deviceOperator);
|
||||||
|
|
||||||
return FsProxyCore.OpenDeviceOperator(out deviceOperator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
public Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return GetBaseStorageService().OpenSdCardDetectionEventNotifier(out eventNotifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
public Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return GetBaseStorageService().OpenGameCardDetectionEventNotifier(out eventNotifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result SimulateDeviceDetectionEvent(SdmmcPort port, SimulatingDeviceDetectionMode mode, bool signalEvent)
|
||||||
|
{
|
||||||
|
return GetBaseStorageService().SimulateDeviceDetectionEvent(port, mode, signalEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
public Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
|
@ -713,6 +714,9 @@ namespace LibHac.FsSrv
|
||||||
ReferenceCountedDisposable<IFileSystem> customFs = null;
|
ReferenceCountedDisposable<IFileSystem> customFs = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
rc = FsProxyCore.OpenCustomStorageFileSystem(out customFs, storageId);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
customFs = StorageLayoutTypeSetFileSystem.CreateShared(ref customFs, storageFlag);
|
customFs = StorageLayoutTypeSetFileSystem.CreateShared(ref customFs, storageFlag);
|
||||||
customFs = AsynchronousAccessFileSystem.CreateShared(ref customFs);
|
customFs = AsynchronousAccessFileSystem.CreateShared(ref customFs);
|
||||||
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref customFs);
|
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref customFs);
|
||||||
|
@ -971,11 +975,6 @@ namespace LibHac.FsSrv
|
||||||
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseFileSystemService GetBaseFileSystemService()
|
|
||||||
{
|
|
||||||
return new BaseFileSystemService(FsProxyCore.Config.BaseFileSystemService, CurrentProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result GetNcaFileSystemService(out NcaFileSystemService ncaFsService)
|
private Result GetNcaFileSystemService(out NcaFileSystemService ncaFsService)
|
||||||
{
|
{
|
||||||
if (NcaFsService is null)
|
if (NcaFsService is null)
|
||||||
|
@ -1000,6 +999,16 @@ namespace LibHac.FsSrv
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BaseStorageService GetBaseStorageService()
|
||||||
|
{
|
||||||
|
return new BaseStorageService(FsProxyCore.Config.BaseStorageService, CurrentProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseFileSystemService GetBaseFileSystemService()
|
||||||
|
{
|
||||||
|
return new BaseFileSystemService(FsProxyCore.Config.BaseFileSystemService, CurrentProcess);
|
||||||
|
}
|
||||||
|
|
||||||
private TimeService GetTimeService()
|
private TimeService GetTimeService()
|
||||||
{
|
{
|
||||||
return new TimeService(FsProxyCore.Config.TimeService, CurrentProcess);
|
return new TimeService(FsProxyCore.Config.TimeService, CurrentProcess);
|
||||||
|
|
|
@ -4,6 +4,7 @@ using LibHac.Fs.Impl;
|
||||||
using LibHac.Fs.Shim;
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSrv.Creators;
|
using LibHac.FsSrv.Creators;
|
||||||
using LibHac.FsSrv.Impl;
|
using LibHac.FsSrv.Impl;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
using LibHac.Sm;
|
using LibHac.Sm;
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv
|
||||||
|
@ -44,10 +45,7 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config);
|
FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config);
|
||||||
|
|
||||||
FsProxyCore = new FileSystemProxyCoreImpl(fspConfig, config.DeviceOperator);
|
FsProxyCore = new FileSystemProxyCoreImpl(fspConfig);
|
||||||
|
|
||||||
FsProxyCore.SetSaveDataIndexerManager(new SaveDataIndexerManager(Hos.Fs, SaveIndexerId,
|
|
||||||
new ArrayPoolMemoryResource(), new SdHandleManager(), false));
|
|
||||||
|
|
||||||
FileSystemProxyImpl fsProxy = GetFileSystemProxyServiceObject();
|
FileSystemProxyImpl fsProxy = GetFileSystemProxyServiceObject();
|
||||||
ulong processId = Hos.Os.GetCurrentProcessId().Value;
|
ulong processId = Hos.Os.GetCurrentProcessId().Value;
|
||||||
|
@ -96,6 +94,13 @@ namespace LibHac.FsSrv
|
||||||
var programRegistryService = new ProgramRegistryServiceImpl(this);
|
var programRegistryService = new ProgramRegistryServiceImpl(this);
|
||||||
var programRegistry = new ProgramRegistryImpl(programRegistryService);
|
var programRegistry = new ProgramRegistryImpl(programRegistryService);
|
||||||
|
|
||||||
|
var baseStorageConfig = new BaseStorageServiceImpl.Configuration();
|
||||||
|
baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator;
|
||||||
|
baseStorageConfig.GameCardStorageCreator = config.FsCreators.GameCardStorageCreator;
|
||||||
|
baseStorageConfig.ProgramRegistry = programRegistry;
|
||||||
|
baseStorageConfig.DeviceOperator = new ReferenceCountedDisposable<IDeviceOperator>(config.DeviceOperator);
|
||||||
|
var baseStorageService = new BaseStorageServiceImpl(in baseStorageConfig);
|
||||||
|
|
||||||
var timeServiceConfig = new TimeServiceImpl.Configuration();
|
var timeServiceConfig = new TimeServiceImpl.Configuration();
|
||||||
timeServiceConfig.HorizonClient = Hos;
|
timeServiceConfig.HorizonClient = Hos;
|
||||||
timeServiceConfig.ProgramRegistry = programRegistry;
|
timeServiceConfig.ProgramRegistry = programRegistry;
|
||||||
|
@ -150,6 +155,7 @@ namespace LibHac.FsSrv
|
||||||
var fspConfig = new FileSystemProxyConfiguration
|
var fspConfig = new FileSystemProxyConfiguration
|
||||||
{
|
{
|
||||||
FsCreatorInterfaces = config.FsCreators,
|
FsCreatorInterfaces = config.FsCreators,
|
||||||
|
BaseStorageService = baseStorageService,
|
||||||
BaseFileSystemService = baseFsService,
|
BaseFileSystemService = baseFsService,
|
||||||
NcaFileSystemService = ncaFsService,
|
NcaFileSystemService = ncaFsService,
|
||||||
SaveDataFileSystemService = saveFsService,
|
SaveDataFileSystemService = saveFsService,
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
using System;
|
using LibHac.Fs;
|
||||||
using LibHac.Common;
|
|
||||||
using LibHac.Fs;
|
|
||||||
using LibHac.Fs.Fsa;
|
|
||||||
using LibHac.FsSrv.Sf;
|
using LibHac.FsSrv.Sf;
|
||||||
using LibHac.FsSystem;
|
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Sf;
|
using LibHac.Sf;
|
||||||
using LibHac.Spl;
|
using LibHac.Spl;
|
||||||
|
@ -75,6 +71,7 @@ namespace LibHac.FsSrv
|
||||||
Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||||
Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||||
Result NotifySystemDataUpdateEvent();
|
Result NotifySystemDataUpdateEvent();
|
||||||
|
Result SimulateDeviceDetectionEvent(SdmmcPort port, SimulatingDeviceDetectionMode mode, bool signalEvent);
|
||||||
|
|
||||||
Result QuerySaveDataTotalSize(out long totalSize, long dataSize, long journalSize);
|
Result QuerySaveDataTotalSize(out long totalSize, long dataSize, long journalSize);
|
||||||
Result VerifySaveDataFileSystem(ulong saveDataId, OutBuffer readBuffer);
|
Result VerifySaveDataFileSystem(ulong saveDataId, OutBuffer readBuffer);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv.Sf
|
||||||
{
|
{
|
||||||
public interface IDeviceOperator : IDisposable
|
public interface IDeviceOperator : IDisposable
|
||||||
{
|
{
|
|
@ -42,6 +42,7 @@ namespace LibHac.FsSystem
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
BaseFileSystem?.Dispose();
|
BaseFileSystem?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
67
src/LibHac/FsSystem/StorageLayoutTypeSetStorage.cs
Normal file
67
src/LibHac/FsSystem/StorageLayoutTypeSetStorage.cs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
using LibHac.Common;
|
||||||
|
using LibHac.Fs;
|
||||||
|
|
||||||
|
namespace LibHac.FsSystem
|
||||||
|
{
|
||||||
|
internal class StorageLayoutTypeSetStorage : IStorage
|
||||||
|
{
|
||||||
|
private ReferenceCountedDisposable<IStorage> BaseStorage { get; }
|
||||||
|
private StorageType StorageFlag { get; }
|
||||||
|
|
||||||
|
protected StorageLayoutTypeSetStorage(ref ReferenceCountedDisposable<IStorage> baseStorage,
|
||||||
|
StorageType storageFlag)
|
||||||
|
{
|
||||||
|
BaseStorage = Shared.Move(ref baseStorage);
|
||||||
|
StorageFlag = storageFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReferenceCountedDisposable<IStorage> CreateShared(
|
||||||
|
ref ReferenceCountedDisposable<IStorage> baseStorage, StorageType storageFlag)
|
||||||
|
{
|
||||||
|
return new ReferenceCountedDisposable<IStorage>(
|
||||||
|
new StorageLayoutTypeSetStorage(ref baseStorage, storageFlag));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
|
BaseStorage?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result DoRead(long offset, Span<byte> destination)
|
||||||
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
|
return BaseStorage.Target.Read(offset, destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source)
|
||||||
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
|
return BaseStorage.Target.Write(offset, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result DoFlush()
|
||||||
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
|
return BaseStorage.Target.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result DoSetSize(long size)
|
||||||
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
|
return BaseStorage.Target.SetSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result DoGetSize(out long size)
|
||||||
|
{
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||||
|
return BaseStorage.Target.GetSize(out size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue