mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Use globals in more places
Adds globals for FileSystemProxyImpl, ProgramRegistryImpl, AccessControl and StorageDeviceManagerFactory
This commit is contained in:
parent
e9918fa5aa
commit
dadc019439
14 changed files with 243 additions and 173 deletions
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;
|
||||
|
@ -31,16 +32,24 @@ namespace LibHac.Fs.Shim
|
|||
}
|
||||
}
|
||||
|
||||
public static string GetCustomStorageDirectoryName(CustomStorageId storageId)
|
||||
public static U8Span GetCustomStorageDirectoryName(CustomStorageId storageId)
|
||||
{
|
||||
switch (storageId)
|
||||
{
|
||||
case CustomStorageId.System:
|
||||
case CustomStorageId.SdCard:
|
||||
return "CustomStorage0";
|
||||
return new U8Span(CustomStorageDirectoryName);
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(storageId), storageId, null);
|
||||
Abort.UnexpectedDefault();
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> CustomStorageDirectoryName => // CustomStorage0
|
||||
new[]
|
||||
{
|
||||
(byte) 'C', (byte) 'u', (byte) 's', (byte) 't', (byte) 'o', (byte) 'm', (byte) 'S', (byte) 't',
|
||||
(byte) 'o', (byte) 'r', (byte) 'a', (byte) 'g', (byte) 'e', (byte) '0'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using LibHac.Common.Keys;
|
||||
using LibHac.Common.Keys;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
|
@ -15,25 +14,6 @@ namespace LibHac.FsSrv.Creators
|
|||
KeySet = keySet;
|
||||
}
|
||||
|
||||
public Result Create(out IFileSystem encryptedFileSystem, IFileSystem baseFileSystem, EncryptedFsKeyId keyId,
|
||||
ReadOnlySpan<byte> encryptionSeed)
|
||||
{
|
||||
encryptedFileSystem = default;
|
||||
|
||||
if (keyId < EncryptedFsKeyId.Save || keyId > EncryptedFsKeyId.CustomStorage)
|
||||
{
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
}
|
||||
|
||||
// todo: "proper" key generation instead of a lazy hack
|
||||
KeySet.SetSdSeed(encryptionSeed.ToArray());
|
||||
|
||||
encryptedFileSystem = new AesXtsFileSystem(baseFileSystem,
|
||||
KeySet.SdCardEncryptionKeys[(int)keyId].DataRo.ToArray(), 0x4000);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> encryptedFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem,
|
||||
EncryptedFsKeyId keyId, in EncryptionSeed encryptionSeed)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace LibHac.FsSrv.Creators
|
||||
{
|
||||
public class FileSystemCreators
|
||||
public class FileSystemCreatorInterfaces
|
||||
{
|
||||
public IRomFileSystemCreator RomFileSystemCreator { get; set; }
|
||||
public IPartitionFileSystemCreator PartitionFileSystemCreator { get; set; }
|
|
@ -1,15 +1,10 @@
|
|||
using System;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
|
||||
namespace LibHac.FsSrv.Creators
|
||||
{
|
||||
public interface IEncryptedFileSystemCreator
|
||||
{
|
||||
// Todo: remove the function using raw IFileSystems
|
||||
Result Create(out IFileSystem encryptedFileSystem, IFileSystem baseFileSystem, EncryptedFsKeyId keyId,
|
||||
ReadOnlySpan<byte> encryptionSeed);
|
||||
|
||||
Result Create(out ReferenceCountedDisposable<IFileSystem> encryptedFileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, EncryptedFsKeyId keyId,
|
||||
in EncryptionSeed encryptionSeed);
|
||||
|
|
|
@ -7,14 +7,14 @@ namespace LibHac.FsSrv
|
|||
{
|
||||
public class DefaultFsServerObjects
|
||||
{
|
||||
public FileSystemCreators FsCreators { get; set; }
|
||||
public FileSystemCreatorInterfaces FsCreators { get; set; }
|
||||
public IDeviceOperator DeviceOperator { get; set; }
|
||||
public EmulatedGameCard GameCard { get; set; }
|
||||
public EmulatedSdCard SdCard { get; set; }
|
||||
|
||||
public static DefaultFsServerObjects GetDefaultEmulatedCreators(IFileSystem rootFileSystem, KeySet keySet)
|
||||
{
|
||||
var creators = new FileSystemCreators();
|
||||
var creators = new FileSystemCreatorInterfaces();
|
||||
var gameCard = new EmulatedGameCard(keySet);
|
||||
var sdCard = new EmulatedSdCard();
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace LibHac.FsSrv
|
|||
{
|
||||
public class FileSystemProxyConfiguration
|
||||
{
|
||||
public FileSystemCreators FsCreatorInterfaces { get; set; }
|
||||
public FileSystemCreatorInterfaces FsCreatorInterfaces { get; set; }
|
||||
public BaseStorageServiceImpl BaseStorageService { get; set; }
|
||||
public BaseFileSystemServiceImpl BaseFileSystemService { get; set; }
|
||||
public NcaFileSystemServiceImpl NcaFileSystemService { get; set; }
|
||||
|
|
|
@ -4,23 +4,20 @@ using LibHac.Fs;
|
|||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSrv.Creators;
|
||||
using LibHac.FsSrv.Impl;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
public class FileSystemProxyCoreImpl
|
||||
{
|
||||
internal FileSystemProxyConfiguration Config { get; }
|
||||
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
||||
internal ProgramRegistryImpl ProgramRegistry { get; }
|
||||
private FileSystemCreatorInterfaces FsCreators { get; }
|
||||
private BaseFileSystemServiceImpl BaseFileSystemService { get; }
|
||||
private EncryptionSeed SdEncryptionSeed { get; set; }
|
||||
|
||||
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
||||
|
||||
private const string NintendoDirectoryName = "Nintendo";
|
||||
|
||||
public FileSystemProxyCoreImpl(FileSystemProxyConfiguration config)
|
||||
public FileSystemProxyCoreImpl(FileSystemCreatorInterfaces fsCreators, BaseFileSystemServiceImpl baseFsService)
|
||||
{
|
||||
Config = config;
|
||||
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
||||
FsCreators = fsCreators;
|
||||
BaseFileSystemService = baseFsService;
|
||||
}
|
||||
|
||||
public Result OpenCloudBackupWorkStorageFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||
|
@ -34,46 +31,62 @@ namespace LibHac.FsSrv
|
|||
{
|
||||
fileSystem = default;
|
||||
|
||||
ReferenceCountedDisposable<IFileSystem> tempFs = null;
|
||||
ReferenceCountedDisposable<IFileSystem> encryptedFs = null;
|
||||
try
|
||||
{
|
||||
Span<byte> path = stackalloc byte[0x40];
|
||||
|
||||
switch (storageId)
|
||||
{
|
||||
case CustomStorageId.SdCard:
|
||||
{
|
||||
Result rc = FsCreators.SdCardFileSystemCreator.Create(out IFileSystem sdFs, false);
|
||||
Result rc = BaseFileSystemService.OpenSdCardProxyFileSystem(out tempFs);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
string customStorageDir = CustomStorage.GetCustomStorageDirectoryName(CustomStorageId.SdCard);
|
||||
string subDirName = $"/{NintendoDirectoryName}/{customStorageDir}";
|
||||
U8Span customStorageDir = CustomStorage.GetCustomStorageDirectoryName(CustomStorageId.SdCard);
|
||||
var sb = new U8StringBuilder(path);
|
||||
sb.Append((byte)'/')
|
||||
.Append(CommonPaths.SdCardNintendoRootDirectoryName)
|
||||
.Append((byte)'/')
|
||||
.Append(customStorageDir);
|
||||
|
||||
rc = Util.CreateSubFileSystem(out IFileSystem subFs, sdFs, subDirName, true);
|
||||
rc = Utility.WrapSubDirectory(out tempFs, ref tempFs, new U8Span(path), true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = FsCreators.EncryptedFileSystemCreator.Create(out IFileSystem encryptedFs, subFs,
|
||||
rc = FsCreators.EncryptedFileSystemCreator.Create(out encryptedFs, tempFs,
|
||||
EncryptedFsKeyId.CustomStorage, SdEncryptionSeed);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(encryptedFs);
|
||||
return Result.Success;
|
||||
}
|
||||
case CustomStorageId.System:
|
||||
{
|
||||
Result rc = FsCreators.BuiltInStorageFileSystemCreator.Create(out IFileSystem userFs, string.Empty,
|
||||
Result rc = BaseFileSystemService.OpenBisFileSystem(out tempFs, U8Span.Empty,
|
||||
BisPartitionId.User);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
string customStorageDir = CustomStorage.GetCustomStorageDirectoryName(CustomStorageId.System);
|
||||
string subDirName = $"/{customStorageDir}";
|
||||
U8Span customStorageDir = CustomStorage.GetCustomStorageDirectoryName(CustomStorageId.System);
|
||||
var sb = new U8StringBuilder(path);
|
||||
sb.Append((byte)'/')
|
||||
.Append(customStorageDir);
|
||||
|
||||
rc = Util.CreateSubFileSystem(out IFileSystem subFs, userFs, subDirName, true);
|
||||
rc = Utility.WrapSubDirectory(out tempFs, ref tempFs, new U8Span(path), true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
// Todo: Get shared object from earlier functions
|
||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(subFs);
|
||||
fileSystem = Shared.Move(ref tempFs);
|
||||
return Result.Success;
|
||||
}
|
||||
default:
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
tempFs?.Dispose();
|
||||
encryptedFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem, U8Span path,
|
||||
bool openCaseSensitive)
|
||||
|
@ -127,7 +140,7 @@ namespace LibHac.FsSrv
|
|||
|
||||
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
||||
{
|
||||
seed.Value.CopyTo(SdEncryptionSeed);
|
||||
SdEncryptionSeed = seed;
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ using LibHac.FsSystem;
|
|||
using LibHac.Ncm;
|
||||
using LibHac.Sf;
|
||||
using LibHac.Spl;
|
||||
using LibHac.Util;
|
||||
using IFileSystem = LibHac.Fs.Fsa.IFileSystem;
|
||||
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;
|
||||
using IFileSf = LibHac.FsSrv.Sf.IFile;
|
||||
|
@ -14,22 +15,64 @@ using IStorageSf = LibHac.FsSrv.Sf.IStorage;
|
|||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
public static class FileSystemProxyImplGlobalMethods
|
||||
{
|
||||
public static void InitializeFileSystemProxy(this FileSystemServer fsSrv,
|
||||
FileSystemProxyConfiguration configuration)
|
||||
{
|
||||
ref FileSystemProxyImplGlobals g = ref fsSrv.Globals.FileSystemProxyImpl;
|
||||
|
||||
g.FileSystemProxyCoreImpl.Set(new FileSystemProxyCoreImpl(configuration.FsCreatorInterfaces,
|
||||
configuration.BaseFileSystemService));
|
||||
|
||||
g.BaseStorageServiceImpl = configuration.BaseStorageService;
|
||||
g.BaseFileSystemServiceImpl = configuration.BaseFileSystemService;
|
||||
g.NcaFileSystemServiceImpl = configuration.NcaFileSystemService;
|
||||
g.SaveDataFileSystemServiceImpl = configuration.SaveDataFileSystemService;
|
||||
g.AccessFailureManagementServiceImpl = configuration.AccessFailureManagementService;
|
||||
g.TimeServiceImpl = configuration.TimeService;
|
||||
g.StatusReportServiceImpl = configuration.StatusReportService;
|
||||
g.ProgramRegistryServiceImpl = configuration.ProgramRegistryService;
|
||||
g.AccessLogServiceImpl = configuration.AccessLogService;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct FileSystemProxyImplGlobals
|
||||
{
|
||||
public NcaFileSystemServiceImpl NcaFileSystemServiceImpl;
|
||||
public SaveDataFileSystemServiceImpl SaveDataFileSystemServiceImpl;
|
||||
public BaseStorageServiceImpl BaseStorageServiceImpl;
|
||||
public BaseFileSystemServiceImpl BaseFileSystemServiceImpl;
|
||||
public AccessFailureManagementServiceImpl AccessFailureManagementServiceImpl;
|
||||
public TimeServiceImpl TimeServiceImpl;
|
||||
public StatusReportServiceImpl StatusReportServiceImpl;
|
||||
public ProgramRegistryServiceImpl ProgramRegistryServiceImpl;
|
||||
public AccessLogServiceImpl AccessLogServiceImpl;
|
||||
public Optional<FileSystemProxyCoreImpl> FileSystemProxyCoreImpl;
|
||||
}
|
||||
|
||||
public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader
|
||||
{
|
||||
private FileSystemServer FsServer { get; }
|
||||
private ref FileSystemProxyImplGlobals Globals => ref FsServer.Globals.FileSystemProxyImpl;
|
||||
|
||||
private FileSystemProxyCoreImpl FsProxyCore { get; }
|
||||
private ReferenceCountedDisposable<NcaFileSystemService> NcaFsService { get; set; }
|
||||
private ReferenceCountedDisposable<SaveDataFileSystemService> SaveFsService { get; set; }
|
||||
private ulong CurrentProcess { get; set; }
|
||||
|
||||
internal FileSystemProxyImpl(FileSystemProxyCoreImpl fsProxyCore)
|
||||
internal FileSystemProxyImpl(FileSystemServer server)
|
||||
{
|
||||
FsProxyCore = fsProxyCore;
|
||||
FsServer = server;
|
||||
|
||||
FsProxyCore = Globals.FileSystemProxyCoreImpl.Value;
|
||||
CurrentProcess = ulong.MaxValue;
|
||||
}
|
||||
|
||||
private Result GetProgramInfo(out ProgramInfo programInfo)
|
||||
{
|
||||
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
||||
var registry = new ProgramRegistryImpl(FsServer);
|
||||
return registry.GetProgramInfo(out programInfo, CurrentProcess);
|
||||
}
|
||||
|
||||
private Result GetNcaFileSystemService(out NcaFileSystemService ncaFsService)
|
||||
|
@ -58,38 +101,37 @@ namespace LibHac.FsSrv
|
|||
|
||||
private BaseStorageService GetBaseStorageService()
|
||||
{
|
||||
return new BaseStorageService(FsProxyCore.Config.BaseStorageService, CurrentProcess);
|
||||
return new BaseStorageService(Globals.BaseStorageServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
private BaseFileSystemService GetBaseFileSystemService()
|
||||
{
|
||||
return new BaseFileSystemService(FsProxyCore.Config.BaseFileSystemService, CurrentProcess);
|
||||
return new BaseFileSystemService(Globals.BaseFileSystemServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
private AccessFailureManagementService GetAccessFailureManagementService()
|
||||
{
|
||||
return new AccessFailureManagementService(FsProxyCore.Config.AccessFailureManagementService,
|
||||
CurrentProcess);
|
||||
return new AccessFailureManagementService(Globals.AccessFailureManagementServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
private TimeService GetTimeService()
|
||||
{
|
||||
return new TimeService(FsProxyCore.Config.TimeService, CurrentProcess);
|
||||
return new TimeService(Globals.TimeServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
private StatusReportService GetStatusReportService()
|
||||
{
|
||||
return new StatusReportService(FsProxyCore.Config.StatusReportService);
|
||||
return new StatusReportService(Globals.StatusReportServiceImpl);
|
||||
}
|
||||
|
||||
private ProgramIndexRegistryService GetProgramIndexRegistryService()
|
||||
{
|
||||
return new ProgramIndexRegistryService(FsProxyCore.Config.ProgramRegistryService, CurrentProcess);
|
||||
return new ProgramIndexRegistryService(Globals.ProgramRegistryServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
private AccessLogService GetAccessLogService()
|
||||
{
|
||||
return new AccessLogService(FsProxyCore.Config.AccessLogService, CurrentProcess);
|
||||
return new AccessLogService(Globals.AccessLogServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
public Result OpenFileSystemWithId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path,
|
||||
|
@ -138,10 +180,8 @@ namespace LibHac.FsSrv
|
|||
CurrentProcess = processId;
|
||||
|
||||
// Initialize the NCA file system service
|
||||
NcaFsService = NcaFileSystemService.CreateShared(FsProxyCore.Config.NcaFileSystemService, processId);
|
||||
|
||||
SaveFsService =
|
||||
SaveDataFileSystemService.CreateShared(FsProxyCore.Config.SaveDataFileSystemService, processId);
|
||||
NcaFsService = NcaFileSystemService.CreateShared(Globals.NcaFileSystemServiceImpl, processId);
|
||||
SaveFsService = SaveDataFileSystemService.CreateShared(Globals.SaveDataFileSystemServiceImpl, processId);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
@ -1055,7 +1095,6 @@ namespace LibHac.FsSrv
|
|||
public Result SetGlobalAccessLogMode(GlobalAccessLogMode mode)
|
||||
{
|
||||
return GetAccessLogService().SetAccessLogMode(mode);
|
||||
|
||||
}
|
||||
|
||||
public Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.Fs.Shim;
|
||||
|
@ -18,19 +17,15 @@ namespace LibHac.FsSrv
|
|||
private const ulong SpeedEmulationProgramIdMinimum = 0x100000000000000;
|
||||
private const ulong SpeedEmulationProgramIdMaximum = 0x100000000001FFF;
|
||||
|
||||
private FileSystemProxyCoreImpl FsProxyCore { get; }
|
||||
public StorageService Storage { get; }
|
||||
internal FileSystemServerImpl Impl => new FileSystemServerImpl(this);
|
||||
public StorageService Storage => new StorageService(this);
|
||||
|
||||
/// <summary>The client instance to be used for internal operations like save indexer access.</summary>
|
||||
public HorizonClient Hos { get; }
|
||||
public HorizonClient Hos => Globals.Hos;
|
||||
|
||||
public bool IsDebugMode { get; }
|
||||
private ITimeSpanGenerator Timer { get; }
|
||||
|
||||
// Functions in the nn::fssrv::detail namespace use this field.
|
||||
// Possibly move this to the main class if the separation doesn't seem necessary.
|
||||
internal FileSystemServerImpl Impl;
|
||||
internal ref FileSystemServerGlobals Globals => ref Impl.Globals;
|
||||
internal FileSystemServerGlobals Globals;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="FileSystemServer"/> and registers its services using the provided HOS client.
|
||||
|
@ -45,21 +40,13 @@ namespace LibHac.FsSrv
|
|||
if (config.DeviceOperator == null)
|
||||
throw new ArgumentException("DeviceOperator must not be null");
|
||||
|
||||
Impl = new FileSystemServerImpl();
|
||||
Impl.Globals.Hos = horizonClient;
|
||||
Impl.Globals.InitMutex = new object();
|
||||
|
||||
Hos = horizonClient;
|
||||
|
||||
Storage = new StorageService(this);
|
||||
|
||||
IsDebugMode = false;
|
||||
Globals.Hos = horizonClient;
|
||||
Globals.InitMutex = new object();
|
||||
|
||||
Timer = config.TimeSpanGenerator ?? new StopWatchTimeSpanGenerator();
|
||||
|
||||
FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config);
|
||||
|
||||
FsProxyCore = new FileSystemProxyCoreImpl(fspConfig);
|
||||
this.InitializeFileSystemProxy(fspConfig);
|
||||
|
||||
FileSystemProxyImpl fsProxy = GetFileSystemProxyServiceObject();
|
||||
ulong processId = Hos.Os.GetCurrentProcessId().Value;
|
||||
|
@ -106,7 +93,9 @@ namespace LibHac.FsSrv
|
|||
new ArrayPoolMemoryResource(), new SdHandleManager(), false);
|
||||
|
||||
var programRegistryService = new ProgramRegistryServiceImpl(this);
|
||||
var programRegistry = new ProgramRegistryImpl(programRegistryService);
|
||||
var programRegistry = new ProgramRegistryImpl(this);
|
||||
|
||||
this.InitializeProgramRegistryImpl(programRegistryService);
|
||||
|
||||
var baseStorageConfig = new BaseStorageServiceImpl.Configuration();
|
||||
baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator;
|
||||
|
@ -200,17 +189,17 @@ namespace LibHac.FsSrv
|
|||
|
||||
private FileSystemProxyImpl GetFileSystemProxyServiceObject()
|
||||
{
|
||||
return new FileSystemProxyImpl(FsProxyCore);
|
||||
return new FileSystemProxyImpl(this);
|
||||
}
|
||||
|
||||
private FileSystemProxyImpl GetFileSystemProxyForLoaderServiceObject()
|
||||
{
|
||||
return new FileSystemProxyImpl(FsProxyCore);
|
||||
return new FileSystemProxyImpl(this);
|
||||
}
|
||||
|
||||
private ProgramRegistryImpl GetProgramRegistryServiceObject()
|
||||
{
|
||||
return new ProgramRegistryImpl(FsProxyCore.Config.ProgramRegistryService);
|
||||
return new ProgramRegistryImpl(this);
|
||||
}
|
||||
|
||||
private class FileSystemProxyService : IServiceObject
|
||||
|
@ -273,9 +262,9 @@ namespace LibHac.FsSrv
|
|||
public class FileSystemServerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="FileSystemCreators"/> used for creating filesystems.
|
||||
/// The <see cref="FileSystemCreatorInterfaces"/> used for creating filesystems.
|
||||
/// </summary>
|
||||
public FileSystemCreators FsCreators { get; set; }
|
||||
public FileSystemCreatorInterfaces FsCreators { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="IDeviceOperator"/> for managing the gamecard and SD card.
|
||||
|
@ -295,42 +284,30 @@ namespace LibHac.FsSrv
|
|||
public ITimeSpanGenerator TimeSpanGenerator { get; set; }
|
||||
}
|
||||
|
||||
public class StorageService
|
||||
public readonly struct StorageService
|
||||
{
|
||||
internal FileSystemServer Fs;
|
||||
private IStorageDeviceManagerFactory _factory;
|
||||
internal readonly FileSystemServer FsSrv;
|
||||
|
||||
internal StorageService(FileSystemServer parentServer)
|
||||
{
|
||||
Fs = parentServer;
|
||||
}
|
||||
|
||||
public void SetStorageDeviceManagerFactory(IStorageDeviceManagerFactory factory)
|
||||
{
|
||||
Assert.NotNull(factory);
|
||||
Assert.Null(_factory);
|
||||
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public IStorageDeviceManagerFactory GetStorageDeviceManagerFactory()
|
||||
{
|
||||
Assert.NotNull(_factory);
|
||||
return _factory;
|
||||
}
|
||||
internal StorageService(FileSystemServer parentServer) => FsSrv = parentServer;
|
||||
}
|
||||
|
||||
// Functions in the nn::fssrv::detail namespace use this struct.
|
||||
// Possibly move this to the main class if the separation doesn't seem necessary.
|
||||
internal struct FileSystemServerImpl
|
||||
public readonly struct FileSystemServerImpl
|
||||
{
|
||||
public FileSystemServerGlobals Globals;
|
||||
internal readonly FileSystemServer FsSrv;
|
||||
|
||||
public FileSystemServerImpl(FileSystemServer parentServer) => FsSrv = parentServer;
|
||||
}
|
||||
|
||||
internal struct FileSystemServerGlobals
|
||||
{
|
||||
public HorizonClient Hos;
|
||||
public object InitMutex;
|
||||
public FileSystemProxyImplGlobals FileSystemProxyImpl;
|
||||
public ProgramRegistryImplGlobals ProgramRegistryImpl;
|
||||
public DeviceEventSimulatorGlobals DeviceEventSimulator;
|
||||
public AccessControlGlobals AccessControl;
|
||||
public StorageDeviceManagerFactoryGlobals StorageDeviceManagerFactory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,19 @@ using LibHac.Util;
|
|||
|
||||
namespace LibHac.FsSrv.Impl
|
||||
{
|
||||
public static class AccessControlGlobalMethods
|
||||
{
|
||||
public static void SetDebugFlagEnabled(this FileSystemServerImpl fsSrv, bool isEnabled)
|
||||
{
|
||||
fsSrv.FsSrv.Globals.AccessControl.DebugFlag = isEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct AccessControlGlobals
|
||||
{
|
||||
public bool DebugFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls access to FS resources for a single process.
|
||||
/// </summary>
|
||||
|
@ -17,15 +30,16 @@ namespace LibHac.FsSrv.Impl
|
|||
/// <br/>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
||||
public class AccessControl
|
||||
{
|
||||
private AccessControlBits? AccessBits { get; }
|
||||
private FileSystemServer FsServer { get; }
|
||||
private ref AccessControlGlobals Globals => ref FsServer.Globals.AccessControl;
|
||||
|
||||
private Optional<AccessControlBits> AccessBits { get; }
|
||||
private LinkedList<ContentOwnerInfo> ContentOwners { get; } = new LinkedList<ContentOwnerInfo>();
|
||||
private LinkedList<SaveDataOwnerInfo> SaveDataOwners { get; } = new LinkedList<SaveDataOwnerInfo>();
|
||||
|
||||
private FileSystemServer FsServer { get; }
|
||||
|
||||
public AccessControl(FileSystemServer fsServer, ReadOnlySpan<byte> accessControlData,
|
||||
ReadOnlySpan<byte> accessControlDescriptor) :
|
||||
this(fsServer, accessControlData, accessControlDescriptor, GetAccessBitsMask(fsServer.IsDebugMode))
|
||||
ReadOnlySpan<byte> accessControlDescriptor) : this(fsServer, accessControlData, accessControlDescriptor,
|
||||
GetAccessBitsMask(fsServer.Globals.AccessControl.DebugFlag))
|
||||
{ }
|
||||
|
||||
public AccessControl(FileSystemServer fsServer, ReadOnlySpan<byte> accessControlData,
|
||||
|
@ -302,7 +316,7 @@ namespace LibHac.FsSrv.Impl
|
|||
case OperationType.ExtendOthersSystemSaveData:
|
||||
return accessBits.CanExtendOthersSystemSaveData();
|
||||
case OperationType.RegisterUpdatePartition:
|
||||
return accessBits.CanRegisterUpdatePartition() && FsServer.IsDebugMode;
|
||||
return accessBits.CanRegisterUpdatePartition() && Globals.DebugFlag;
|
||||
case OperationType.OpenSaveDataTransferManager:
|
||||
return accessBits.CanOpenSaveDataTransferManager();
|
||||
case OperationType.OpenSaveDataTransferManagerVersion2:
|
||||
|
@ -465,7 +479,7 @@ namespace LibHac.FsSrv.Impl
|
|||
case AccessibilityType.MountHost:
|
||||
return new Accessibility(accessBits.CanMountHostRead(), accessBits.CanMountHostWrite());
|
||||
case AccessibilityType.MountRegisteredUpdatePartition:
|
||||
return new Accessibility(accessBits.CanMountRegisteredUpdatePartitionRead() && FsServer.IsDebugMode, false);
|
||||
return new Accessibility(accessBits.CanMountRegisteredUpdatePartitionRead() && Globals.DebugFlag, false);
|
||||
case AccessibilityType.MountSaveDataInternalStorage:
|
||||
return new Accessibility(accessBits.CanOpenSaveDataInternalStorageRead(), accessBits.CanOpenSaveDataInternalStorageWrite());
|
||||
case AccessibilityType.MountTemporaryDirectory:
|
||||
|
|
|
@ -14,27 +14,27 @@ namespace LibHac.FsSrv.Impl
|
|||
|
||||
internal static class DeviceEventSimulatorGlobalMethods
|
||||
{
|
||||
public static SdCardEventSimulator GetSdCardEventSimulator(this ref FileSystemServerImpl fs)
|
||||
public static SdCardEventSimulator GetSdCardEventSimulator(this FileSystemServerImpl fs)
|
||||
{
|
||||
ref DeviceEventSimulatorGlobals g = ref fs.Globals.DeviceEventSimulator;
|
||||
using var guard = new InitializationGuard(ref g.SdCardEventSimulatorInit, fs.Globals.InitMutex);
|
||||
ref DeviceEventSimulatorGlobals g = ref fs.FsSrv.Globals.DeviceEventSimulator;
|
||||
using var guard = new InitializationGuard(ref g.SdCardEventSimulatorInit, fs.FsSrv.Globals.InitMutex);
|
||||
|
||||
if (guard.IsInitialized)
|
||||
return g.SdCardEventSimulator;
|
||||
|
||||
g.SdCardEventSimulator = new SdCardEventSimulator(fs.Globals.Hos.Os);
|
||||
g.SdCardEventSimulator = new SdCardEventSimulator(fs.FsSrv.Globals.Hos.Os);
|
||||
return g.SdCardEventSimulator;
|
||||
}
|
||||
|
||||
public static GameCardEventSimulator GetGameCardEventSimulator(this ref FileSystemServerImpl fs)
|
||||
public static GameCardEventSimulator GetGameCardEventSimulator(this FileSystemServerImpl fs)
|
||||
{
|
||||
ref DeviceEventSimulatorGlobals g = ref fs.Globals.DeviceEventSimulator;
|
||||
using var guard = new InitializationGuard(ref g.GameCardEventSimulatorInit, fs.Globals.InitMutex);
|
||||
ref DeviceEventSimulatorGlobals g = ref fs.FsSrv.Globals.DeviceEventSimulator;
|
||||
using var guard = new InitializationGuard(ref g.GameCardEventSimulatorInit, fs.FsSrv.Globals.InitMutex);
|
||||
|
||||
if (guard.IsInitialized)
|
||||
return g.GameCardEventSimulator;
|
||||
|
||||
g.GameCardEventSimulator = new GameCardEventSimulator(fs.Globals.Hos.Os);
|
||||
g.GameCardEventSimulator = new GameCardEventSimulator(fs.FsSrv.Globals.Hos.Os);
|
||||
return g.GameCardEventSimulator;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,20 @@ using LibHac.Sf;
|
|||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
public static class ProgramRegistryImplGlobalMethods
|
||||
{
|
||||
public static void InitializeProgramRegistryImpl(this FileSystemServer fsSrv,
|
||||
ProgramRegistryServiceImpl serviceImpl)
|
||||
{
|
||||
fsSrv.Globals.ProgramRegistryImpl.ServiceImpl = serviceImpl;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ProgramRegistryImplGlobals
|
||||
{
|
||||
public ProgramRegistryServiceImpl ServiceImpl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to add, remove or access the Program Registry.
|
||||
/// </summary>
|
||||
|
@ -16,21 +30,15 @@ namespace LibHac.FsSrv
|
|||
/// <br/>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
||||
public class ProgramRegistryImpl : IProgramRegistry
|
||||
{
|
||||
private FileSystemServer _fsServer;
|
||||
private ulong _processId;
|
||||
|
||||
// Note: FS keeps this object as a global variable
|
||||
private readonly ProgramRegistryServiceImpl _registryService;
|
||||
private ref ProgramRegistryImplGlobals Globals => ref _fsServer.Globals.ProgramRegistryImpl;
|
||||
|
||||
public ProgramRegistryImpl(ProgramRegistryServiceImpl registryService)
|
||||
public ProgramRegistryImpl(FileSystemServer server)
|
||||
{
|
||||
_fsServer = server;
|
||||
_processId = ulong.MaxValue;
|
||||
_registryService = registryService;
|
||||
}
|
||||
|
||||
public ProgramRegistryImpl(ProgramRegistryServiceImpl registryService, ulong processId)
|
||||
{
|
||||
_processId = processId;
|
||||
_registryService = registryService;
|
||||
}
|
||||
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
|
@ -43,7 +51,7 @@ namespace LibHac.FsSrv
|
|||
if (!ProgramInfo.IsInitialProgram(_processId))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _registryService.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
||||
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
||||
accessControlDescriptor.Buffer);
|
||||
}
|
||||
|
||||
|
@ -56,19 +64,19 @@ namespace LibHac.FsSrv
|
|||
if (!ProgramInfo.IsInitialProgram(_processId))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _registryService.UnregisterProgramInfo(processId);
|
||||
return Globals.ServiceImpl.UnregisterProgramInfo(processId);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||
{
|
||||
return _registryService.GetProgramInfo(out programInfo, processId);
|
||||
return Globals.ServiceImpl.GetProgramInfo(out programInfo, processId);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||
{
|
||||
return _registryService.GetProgramInfoByProgramId(out programInfo, programId);
|
||||
return Globals.ServiceImpl.GetProgramInfoByProgramId(out programInfo, programId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace LibHac.FsSrv.Storage
|
|||
|
||||
tempStorage = StorageServiceObjectAdapter.CreateShared(ref sdCardStorage);
|
||||
|
||||
SdCardEventSimulator eventSimulator = service.Fs.Impl.GetSdCardEventSimulator();
|
||||
SdCardEventSimulator eventSimulator = service.FsSrv.Impl.GetSdCardEventSimulator();
|
||||
tempStorage = DeviceEventSimulationStorage.CreateShared(ref tempStorage, eventSimulator);
|
||||
|
||||
tempStorage = SpeedEmulationStorage.CreateShared(ref tempStorage);
|
||||
|
|
|
@ -1,17 +1,52 @@
|
|||
using LibHac.Diag;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.FsSrv.Storage.Sf;
|
||||
|
||||
namespace LibHac.FsSrv.Storage
|
||||
{
|
||||
internal struct StorageDeviceManagerFactoryGlobals
|
||||
{
|
||||
public nint FactoryGuard;
|
||||
public IStorageDeviceManagerFactory Factory;
|
||||
}
|
||||
|
||||
public static class StorageDeviceManagerFactoryApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the <see cref="IStorageDeviceManagerFactory"/> to be used by the <see cref="FileSystemServer"/>.
|
||||
/// Calling this method more than once will do nothing.
|
||||
/// </summary>
|
||||
/// <param name="storage">The Storage instance to use.</param>
|
||||
/// <param name="factory">The <see cref="IStorageDeviceManagerFactory"/> to be used by this Storage instance.</param>
|
||||
public static void InitializeStorageDeviceManagerFactory(this StorageService storage,
|
||||
IStorageDeviceManagerFactory factory)
|
||||
{
|
||||
storage.GetStorageDeviceManagerFactory(factory);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class StorageDeviceManagerFactory
|
||||
{
|
||||
public static Result CreateStorageDeviceManager(this StorageService storage,
|
||||
out ReferenceCountedDisposable<IStorageDeviceManager> deviceManager, StorageDevicePortId portId)
|
||||
{
|
||||
IStorageDeviceManagerFactory factory = storage.GetStorageDeviceManagerFactory();
|
||||
IStorageDeviceManagerFactory factory = storage.GetStorageDeviceManagerFactory(null);
|
||||
Assert.NotNull(factory);
|
||||
|
||||
return factory.Create(out deviceManager, portId);
|
||||
}
|
||||
|
||||
public static IStorageDeviceManagerFactory GetStorageDeviceManagerFactory(this StorageService storage,
|
||||
IStorageDeviceManagerFactory factory)
|
||||
{
|
||||
ref StorageDeviceManagerFactoryGlobals g = ref storage.FsSrv.Globals.StorageDeviceManagerFactory;
|
||||
using var initGuard = new InitializationGuard(ref g.FactoryGuard, storage.FsSrv.Globals.InitMutex);
|
||||
|
||||
if (initGuard.IsInitialized)
|
||||
return g.Factory;
|
||||
|
||||
g.Factory = factory;
|
||||
return g.Factory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue