Add BaseStorageService

This commit is contained in:
Alex Barney 2020-11-05 01:15:21 -07:00
parent c29fed67c1
commit 6b6a31dcea
15 changed files with 370 additions and 114 deletions

View file

@ -190,4 +190,11 @@ namespace LibHac.Fs
None = 0, None = 0,
PseudoCaseSensitive = 1 PseudoCaseSensitive = 1
} }
public enum SimulatingDeviceDetectionMode
{
None = 0,
Inserted = 1,
NotInserted = 2
}
} }

View 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);
}
}
}

View file

@ -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();
} }

View file

@ -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();
} }
} }

View file

@ -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);
} }
} }

View file

@ -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
{ {

View file

@ -1,4 +1,5 @@
using LibHac.Fs; using LibHac.Fs;
using LibHac.FsSrv.Sf;
namespace LibHac.FsSrv namespace LibHac.FsSrv
{ {

View file

@ -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; }

View file

@ -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;
}
} }
} }

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -1,6 +1,6 @@
using System; using System;
namespace LibHac.FsSrv namespace LibHac.FsSrv.Sf
{ {
public interface IDeviceOperator : IDisposable public interface IDeviceOperator : IDisposable
{ {

View file

@ -42,6 +42,7 @@ namespace LibHac.FsSystem
{ {
if (disposing) if (disposing)
{ {
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(StorageFlag);
BaseFileSystem?.Dispose(); BaseFileSystem?.Dispose();
} }

View 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);
}
}
}