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,
|
||||
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;
|
||||
}
|
||||
|
||||
public Result CreateNormal(GameCardHandle handle, out IStorage storage)
|
||||
public Result CreateReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage)
|
||||
{
|
||||
storage = default;
|
||||
|
||||
|
@ -21,16 +21,17 @@ namespace LibHac.FsSrv.Creators
|
|||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
public Result CreateSecure(GameCardHandle handle, out IStorage storage)
|
||||
public Result CreateSecureReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage)
|
||||
{
|
||||
storage = default;
|
||||
|
||||
|
@ -48,16 +49,19 @@ namespace LibHac.FsSrv.Creators
|
|||
rc = GameCard.GetGameCardImageHash(imageHash);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
public Result CreateWritable(GameCardHandle handle, out IStorage storage)
|
||||
public Result CreateWriteOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace LibHac.FsSrv.Creators
|
|||
{
|
||||
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
|
||||
{
|
||||
Result CreateNormal(GameCardHandle handle, out IStorage storage);
|
||||
Result CreateSecure(GameCardHandle handle, out IStorage storage);
|
||||
Result CreateWritable(GameCardHandle handle, out IStorage storage);
|
||||
Result CreateReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage);
|
||||
Result CreateSecureReadOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage);
|
||||
Result CreateWriteOnly(GameCardHandle handle, out ReferenceCountedDisposable<IStorage> storage);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using LibHac.Common.Keys;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSrv.Creators;
|
||||
using LibHac.FsSrv.Sf;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Sf;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace LibHac.FsSrv
|
|||
public class FileSystemProxyConfiguration
|
||||
{
|
||||
public FileSystemCreators FsCreatorInterfaces { get; set; }
|
||||
public BaseStorageServiceImpl BaseStorageService { get; set; }
|
||||
public BaseFileSystemServiceImpl BaseFileSystemService { get; set; }
|
||||
public NcaFileSystemServiceImpl NcaFileSystemService { get; set; }
|
||||
public SaveDataFileSystemServiceImpl SaveDataFileSystemService { get; set; }
|
||||
|
|
|
@ -4,8 +4,6 @@ using LibHac.Fs;
|
|||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSrv.Creators;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
|
@ -15,67 +13,14 @@ namespace LibHac.FsSrv
|
|||
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
||||
internal ProgramRegistryImpl ProgramRegistry { get; }
|
||||
|
||||
private ReferenceCountedDisposable<IDeviceOperator> DeviceOperator { get; }
|
||||
|
||||
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
||||
|
||||
private const string NintendoDirectoryName = "Nintendo";
|
||||
|
||||
private GlobalAccessLogMode LogMode { get; set; }
|
||||
|
||||
internal ISaveDataIndexerManager SaveDataIndexerManager { get; private set; }
|
||||
|
||||
public FileSystemProxyCoreImpl(FileSystemProxyConfiguration config, IDeviceOperator deviceOperator)
|
||||
public FileSystemProxyCoreImpl(FileSystemProxyConfiguration config)
|
||||
{
|
||||
Config = config;
|
||||
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,
|
||||
|
@ -177,29 +122,7 @@ namespace LibHac.FsSrv
|
|||
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
||||
{
|
||||
seed.Value.CopyTo(SdEncryptionSeed);
|
||||
// todo: FsCreators.SaveDataFileSystemCreator.SetSdCardEncryptionSeed(seed);
|
||||
|
||||
SaveDataIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdSystem);
|
||||
SaveDataIndexerManager.InvalidateIndexer(SaveDataSpaceId.SdCache);
|
||||
|
||||
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)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetBaseStorageService().OpenBisStorage(out storage, partitionId);
|
||||
}
|
||||
|
||||
public Result InvalidateBisCache()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetBaseStorageService().InvalidateBisCache();
|
||||
}
|
||||
|
||||
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,
|
||||
GameCardPartitionRaw partitionId)
|
||||
{
|
||||
// Missing permission check and StorageInterfaceAdapter
|
||||
|
||||
return FsProxyCore.OpenGameCardStorage(out storage, handle, partitionId);
|
||||
return GetBaseStorageService().OpenGameCardStorage(out storage, handle, partitionId);
|
||||
}
|
||||
|
||||
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||
{
|
||||
// Missing permission check
|
||||
|
||||
return FsProxyCore.OpenDeviceOperator(out deviceOperator);
|
||||
return GetBaseStorageService().OpenDeviceOperator(out deviceOperator);
|
||||
}
|
||||
|
||||
public Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetBaseStorageService().OpenSdCardDetectionEventNotifier(out 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)
|
||||
|
@ -713,6 +714,9 @@ namespace LibHac.FsSrv
|
|||
ReferenceCountedDisposable<IFileSystem> customFs = null;
|
||||
try
|
||||
{
|
||||
rc = FsProxyCore.OpenCustomStorageFileSystem(out customFs, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
customFs = StorageLayoutTypeSetFileSystem.CreateShared(ref customFs, storageFlag);
|
||||
customFs = AsynchronousAccessFileSystem.CreateShared(ref customFs);
|
||||
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref customFs);
|
||||
|
@ -971,11 +975,6 @@ namespace LibHac.FsSrv
|
|||
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
||||
}
|
||||
|
||||
private BaseFileSystemService GetBaseFileSystemService()
|
||||
{
|
||||
return new BaseFileSystemService(FsProxyCore.Config.BaseFileSystemService, CurrentProcess);
|
||||
}
|
||||
|
||||
private Result GetNcaFileSystemService(out NcaFileSystemService ncaFsService)
|
||||
{
|
||||
if (NcaFsService is null)
|
||||
|
@ -1000,6 +999,16 @@ namespace LibHac.FsSrv
|
|||
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()
|
||||
{
|
||||
return new TimeService(FsProxyCore.Config.TimeService, CurrentProcess);
|
||||
|
|
|
@ -4,6 +4,7 @@ using LibHac.Fs.Impl;
|
|||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSrv.Creators;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Sm;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
|
@ -44,10 +45,7 @@ namespace LibHac.FsSrv
|
|||
|
||||
FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config);
|
||||
|
||||
FsProxyCore = new FileSystemProxyCoreImpl(fspConfig, config.DeviceOperator);
|
||||
|
||||
FsProxyCore.SetSaveDataIndexerManager(new SaveDataIndexerManager(Hos.Fs, SaveIndexerId,
|
||||
new ArrayPoolMemoryResource(), new SdHandleManager(), false));
|
||||
FsProxyCore = new FileSystemProxyCoreImpl(fspConfig);
|
||||
|
||||
FileSystemProxyImpl fsProxy = GetFileSystemProxyServiceObject();
|
||||
ulong processId = Hos.Os.GetCurrentProcessId().Value;
|
||||
|
@ -96,6 +94,13 @@ namespace LibHac.FsSrv
|
|||
var programRegistryService = new ProgramRegistryServiceImpl(this);
|
||||
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();
|
||||
timeServiceConfig.HorizonClient = Hos;
|
||||
timeServiceConfig.ProgramRegistry = programRegistry;
|
||||
|
@ -150,6 +155,7 @@ namespace LibHac.FsSrv
|
|||
var fspConfig = new FileSystemProxyConfiguration
|
||||
{
|
||||
FsCreatorInterfaces = config.FsCreators,
|
||||
BaseStorageService = baseStorageService,
|
||||
BaseFileSystemService = baseFsService,
|
||||
NcaFileSystemService = ncaFsService,
|
||||
SaveDataFileSystemService = saveFsService,
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Sf;
|
||||
using LibHac.Spl;
|
||||
|
@ -75,6 +71,7 @@ namespace LibHac.FsSrv
|
|||
Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||
Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||
Result NotifySystemDataUpdateEvent();
|
||||
Result SimulateDeviceDetectionEvent(SdmmcPort port, SimulatingDeviceDetectionMode mode, bool signalEvent);
|
||||
|
||||
Result QuerySaveDataTotalSize(out long totalSize, long dataSize, long journalSize);
|
||||
Result VerifySaveDataFileSystem(ulong saveDataId, OutBuffer readBuffer);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
namespace LibHac.FsSrv.Sf
|
||||
{
|
||||
public interface IDeviceOperator : IDisposable
|
||||
{
|
|
@ -42,6 +42,7 @@ namespace LibHac.FsSystem
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
|
||||
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