From e50078d9395040e1b24b41d75c4ee7e781297412 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Sun, 7 Feb 2021 00:26:20 -0700 Subject: [PATCH] Move initialization code out of FileSystemServer --- src/LibHac/Fs/SaveData.cs | 7 + src/LibHac/FsSrv/FileSystemServer.cs | 257 ++---------------- .../FsSrv/FileSystemServerInitializer.cs | 243 +++++++++++++++++ src/LibHac/FsSrv/SaveDataFileSystemService.cs | 18 +- src/LibHac/Horizon.cs | 12 +- src/LibHac/HorizonFactory.cs | 23 ++ .../FileSystemServerFactory.cs | 2 +- tests/LibHac.Tests/HorizonFactory.cs | 2 +- 8 files changed, 303 insertions(+), 261 deletions(-) create mode 100644 src/LibHac/Fs/SaveData.cs create mode 100644 src/LibHac/FsSrv/FileSystemServerInitializer.cs create mode 100644 src/LibHac/HorizonFactory.cs diff --git a/src/LibHac/Fs/SaveData.cs b/src/LibHac/Fs/SaveData.cs new file mode 100644 index 00000000..1ea6955e --- /dev/null +++ b/src/LibHac/Fs/SaveData.cs @@ -0,0 +1,7 @@ +namespace LibHac.Fs +{ + public static class SaveData + { + public const ulong SaveIndexerId = 0x8000000000000000; + } +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/FileSystemServer.cs b/src/LibHac/FsSrv/FileSystemServer.cs index c8ee9b00..7074498d 100644 --- a/src/LibHac/FsSrv/FileSystemServer.cs +++ b/src/LibHac/FsSrv/FileSystemServer.cs @@ -1,24 +1,12 @@ -using System; -using LibHac.Fs.Impl; -using LibHac.Fs.Shim; -using LibHac.FsSrv.Creators; -using LibHac.FsSrv.Impl; -using LibHac.FsSrv.Sf; +using LibHac.FsSrv.Impl; using LibHac.FsSrv.Storage; -using LibHac.Sm; namespace LibHac.FsSrv { public class FileSystemServer { - internal const ulong SaveIndexerId = 0x8000000000000000; - - private const ulong SpeedEmulationProgramIdMinimum = 0x100000000000000; - private const ulong SpeedEmulationProgramIdMaximum = 0x100000000001FFF; - internal FileSystemServerGlobals Globals; - private HorizonClient Hos => Globals.Hos; public FileSystemServerImpl Impl => new FileSystemServerImpl(this); public StorageService Storage => new StorageService(this); @@ -26,236 +14,11 @@ namespace LibHac.FsSrv /// Creates a new and registers its services using the provided HOS client. /// /// The that will be used by this server. - /// The configuration for the created . - public FileSystemServer(HorizonClient horizonClient, FileSystemServerConfig config) + public FileSystemServer(HorizonClient horizonClient) { - if (config.FsCreators == null) - throw new ArgumentException("FsCreators must not be null"); - - if (config.DeviceOperator == null) - throw new ArgumentException("DeviceOperator must not be null"); - Globals.Hos = horizonClient; Globals.InitMutex = new object(); - - FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config); - this.InitializeFileSystemProxy(fspConfig); - - using ReferenceCountedDisposable fsProxy = Impl.GetFileSystemProxyServiceObject(); - ulong processId = Hos.Os.GetCurrentProcessId().Value; - fsProxy.Target.SetCurrentProcess(processId).IgnoreResult(); - - Hos.Fs.InitializeDfcFileSystemProxyServiceObject(fsProxy); - - var saveService = new SaveDataFileSystemService(fspConfig.SaveDataFileSystemService, processId); - - saveService.CleanUpTemporaryStorage().IgnoreResult(); - saveService.CleanUpSaveData().IgnoreResult(); - saveService.CompleteSaveDataExtension().IgnoreResult(); - saveService.FixSaveData().IgnoreResult(); - saveService.RecoverMultiCommit().IgnoreResult(); - - Hos.Sm.RegisterService(new FileSystemProxyService(this), "fsp-srv").IgnoreResult(); - Hos.Sm.RegisterService(new FileSystemProxyForLoaderService(this), "fsp-ldr").IgnoreResult(); - Hos.Sm.RegisterService(new ProgramRegistryService(this), "fsp-pr").IgnoreResult(); - - // NS usually takes care of this - if (Hos.Fs.IsSdCardInserted()) - Hos.Fs.SetSdCardAccessibility(true); } - - private FileSystemProxyConfiguration InitializeFileSystemProxyConfiguration(FileSystemServerConfig config) - { - var saveDataIndexerManager = new SaveDataIndexerManager(Hos.Fs, SaveIndexerId, - new ArrayPoolMemoryResource(), new SdHandleManager(), false); - - var programRegistryService = new ProgramRegistryServiceImpl(this); - - this.InitializeProgramRegistryImpl(programRegistryService); - - var baseStorageConfig = new BaseStorageServiceImpl.Configuration(); - baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator; - baseStorageConfig.GameCardStorageCreator = config.FsCreators.GameCardStorageCreator; - baseStorageConfig.FsServer = this; - baseStorageConfig.DeviceOperator = new ReferenceCountedDisposable(config.DeviceOperator); - var baseStorageService = new BaseStorageServiceImpl(in baseStorageConfig); - - var timeService = new TimeServiceImpl(this); - - var baseFsServiceConfig = new BaseFileSystemServiceImpl.Configuration(); - baseFsServiceConfig.BisFileSystemCreator = config.FsCreators.BuiltInStorageFileSystemCreator; - baseFsServiceConfig.GameCardFileSystemCreator = config.FsCreators.GameCardFileSystemCreator; - baseFsServiceConfig.SdCardFileSystemCreator = config.FsCreators.SdCardFileSystemCreator; - baseFsServiceConfig.BisWiperCreator = BisWiper.CreateWiper; - baseFsServiceConfig.FsServer = this; - var baseFsService = new BaseFileSystemServiceImpl(in baseFsServiceConfig); - - var accessFailureManagementServiceConfig = new AccessFailureManagementServiceImpl.Configuration(); - accessFailureManagementServiceConfig.FsServer = this; - - var accessFailureManagementService = - new AccessFailureManagementServiceImpl(in accessFailureManagementServiceConfig); - - var speedEmulationRange = - new InternalProgramIdRangeForSpeedEmulation(SpeedEmulationProgramIdMinimum, - SpeedEmulationProgramIdMaximum); - - var ncaFsServiceConfig = new NcaFileSystemServiceImpl.Configuration(); - ncaFsServiceConfig.BaseFsService = baseFsService; - ncaFsServiceConfig.HostFsCreator = config.FsCreators.HostFileSystemCreator; - ncaFsServiceConfig.TargetManagerFsCreator = config.FsCreators.TargetManagerFileSystemCreator; - ncaFsServiceConfig.PartitionFsCreator = config.FsCreators.PartitionFileSystemCreator; - ncaFsServiceConfig.RomFsCreator = config.FsCreators.RomFileSystemCreator; - ncaFsServiceConfig.StorageOnNcaCreator = config.FsCreators.StorageOnNcaCreator; - ncaFsServiceConfig.SubDirectoryFsCreator = config.FsCreators.SubDirectoryFileSystemCreator; - ncaFsServiceConfig.EncryptedFsCreator = config.FsCreators.EncryptedFileSystemCreator; - ncaFsServiceConfig.ProgramRegistryService = programRegistryService; - ncaFsServiceConfig.AccessFailureManagementService = accessFailureManagementService; - ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange; - ncaFsServiceConfig.FsServer = this; - - var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig, config.ExternalKeySet); - - var saveFsServiceConfig = new SaveDataFileSystemServiceImpl.Configuration(); - saveFsServiceConfig.BaseFsService = baseFsService; - saveFsServiceConfig.HostFsCreator = config.FsCreators.HostFileSystemCreator; - saveFsServiceConfig.TargetManagerFsCreator = config.FsCreators.TargetManagerFileSystemCreator; - saveFsServiceConfig.SaveFsCreator = config.FsCreators.SaveDataFileSystemCreator; - saveFsServiceConfig.EncryptedFsCreator = config.FsCreators.EncryptedFileSystemCreator; - saveFsServiceConfig.ProgramRegistryService = programRegistryService; - saveFsServiceConfig.ShouldCreateDirectorySaveData = () => true; - saveFsServiceConfig.SaveIndexerManager = saveDataIndexerManager; - saveFsServiceConfig.FsServer = this; - - var saveFsService = new SaveDataFileSystemServiceImpl(in saveFsServiceConfig); - - var statusReportServiceConfig = new StatusReportServiceImpl.Configuration(); - statusReportServiceConfig.NcaFsServiceImpl = ncaFsService; - statusReportServiceConfig.SaveFsServiceImpl = saveFsService; - statusReportServiceConfig.BufferManagerMemoryReport = null; - statusReportServiceConfig.ExpHeapMemoryReport = null; - statusReportServiceConfig.BufferPoolMemoryReport = null; - statusReportServiceConfig.GetPatrolAllocateCounts = null; - statusReportServiceConfig.MainThreadStackUsageReporter = new DummyStackUsageReporter(); - statusReportServiceConfig.IpcWorkerThreadStackUsageReporter = new DummyStackUsageReporter(); - statusReportServiceConfig.PipeLineWorkerThreadStackUsageReporter = new DummyStackUsageReporter(); - statusReportServiceConfig.FsServer = this; - - var statusReportService = new StatusReportServiceImpl(in statusReportServiceConfig); - - var accessLogServiceConfig = new AccessLogServiceImpl.Configuration(); - accessLogServiceConfig.MinimumProgramIdForSdCardLog = 0x0100000000003000; - accessLogServiceConfig.FsServer = this; - - var accessLogService = new AccessLogServiceImpl(in accessLogServiceConfig); - - var fspConfig = new FileSystemProxyConfiguration - { - FsCreatorInterfaces = config.FsCreators, - BaseStorageService = baseStorageService, - BaseFileSystemService = baseFsService, - NcaFileSystemService = ncaFsService, - SaveDataFileSystemService = saveFsService, - AccessFailureManagementService = accessFailureManagementService, - TimeService = timeService, - StatusReportService = statusReportService, - ProgramRegistryService = programRegistryService, - AccessLogService = accessLogService - }; - - return fspConfig; - } - - private class FileSystemProxyService : IServiceObject - { - private readonly FileSystemServer _server; - - public FileSystemProxyService(FileSystemServer server) - { - _server = server; - } - - public Result GetServiceObject(out object serviceObject) - { - serviceObject = _server.Impl.GetFileSystemProxyServiceObject(); - return Result.Success; - } - } - - private class FileSystemProxyForLoaderService : IServiceObject - { - private readonly FileSystemServer _server; - - public FileSystemProxyForLoaderService(FileSystemServer server) - { - _server = server; - } - - public Result GetServiceObject(out object serviceObject) - { - serviceObject = _server.Impl.GetFileSystemProxyForLoaderServiceObject(); - return Result.Success; - } - } - - private class ProgramRegistryService : IServiceObject - { - private readonly FileSystemServer _server; - - public ProgramRegistryService(FileSystemServer server) - { - _server = server; - } - - public Result GetServiceObject(out object serviceObject) - { - serviceObject = _server.Impl.GetProgramRegistryServiceObject(); - return Result.Success; - } - } - - private class DummyStackUsageReporter : IStackUsageReporter - { - public uint GetStackUsage() => 0; - } - } - - /// - /// Contains the configuration for creating a new . - /// - public class FileSystemServerConfig - { - /// - /// The used for creating filesystems. - /// - public FileSystemCreatorInterfaces FsCreators { get; set; } - - /// - /// An for managing the gamecard and SD card. - /// - public IDeviceOperator DeviceOperator { get; set; } - - /// - /// A keyset containing rights IDs and title keys. - /// If null, an empty set will be created. - /// - public ExternalKeySet ExternalKeySet { get; set; } - } - - public readonly struct StorageService - { - internal readonly FileSystemServer FsSrv; - - 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. - public readonly struct FileSystemServerImpl - { - internal readonly FileSystemServer FsSrv; - - public FileSystemServerImpl(FileSystemServer parentServer) => FsSrv = parentServer; } internal struct FileSystemServerGlobals @@ -268,4 +31,20 @@ namespace LibHac.FsSrv public AccessControlGlobals AccessControl; public StorageDeviceManagerFactoryGlobals StorageDeviceManagerFactory; } + + // Functions in the nn::fssrv::storage namespace use this struct. + public readonly struct StorageService + { + internal readonly FileSystemServer FsSrv; + + internal StorageService(FileSystemServer parentServer) => FsSrv = parentServer; + } + + // Functions in the nn::fssrv::detail namespace use this struct. + public readonly struct FileSystemServerImpl + { + internal readonly FileSystemServer FsSrv; + + public FileSystemServerImpl(FileSystemServer parentServer) => FsSrv = parentServer; + } } diff --git a/src/LibHac/FsSrv/FileSystemServerInitializer.cs b/src/LibHac/FsSrv/FileSystemServerInitializer.cs new file mode 100644 index 00000000..db7b3b72 --- /dev/null +++ b/src/LibHac/FsSrv/FileSystemServerInitializer.cs @@ -0,0 +1,243 @@ +using System; +using LibHac.Fs.Impl; +using LibHac.Fs.Shim; +using LibHac.FsSrv.Creators; +using LibHac.FsSrv.Impl; +using LibHac.FsSrv.Sf; +using LibHac.FsSrv.Storage; +using LibHac.Sm; + +namespace LibHac.FsSrv +{ + public static class FileSystemServerInitializer + { + private const ulong SpeedEmulationProgramIdMinimum = 0x100000000000000; + private const ulong SpeedEmulationProgramIdMaximum = 0x100000000001FFF; + + /// + /// Initializes a with the provided . + /// + /// The that was created with. + /// The to initialize. + /// The config for initializing . + public static void InitializeWithConfig(HorizonClient client, FileSystemServer server, FileSystemServerConfig config) + { + if (config.FsCreators == null) + throw new ArgumentException("FsCreators must not be null"); + + if (config.DeviceOperator == null) + throw new ArgumentException("DeviceOperator must not be null"); + + server.SetDebugFlagEnabled(false); + server.Storage.InitializeStorageDeviceManagerFactory(null); + + FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxy(server, config); + + using ReferenceCountedDisposable fsProxy = server.Impl.GetFileSystemProxyServiceObject(); + ulong processId = client.Os.GetCurrentProcessId().Value; + fsProxy.Target.SetCurrentProcess(processId).IgnoreResult(); + + client.Fs.InitializeDfcFileSystemProxyServiceObject(fsProxy); + + InitializeFileSystemProxyServer(client, server); + + var saveService = new SaveDataFileSystemService(fspConfig.SaveDataFileSystemService, processId); + + saveService.CleanUpTemporaryStorage().IgnoreResult(); + saveService.CleanUpSaveData().IgnoreResult(); + saveService.CompleteSaveDataExtension().IgnoreResult(); + saveService.FixSaveData().IgnoreResult(); + saveService.RecoverMultiCommit().IgnoreResult(); + + // NS usually takes care of this + if (client.Fs.IsSdCardInserted()) + client.Fs.SetSdCardAccessibility(true); + } + + private static FileSystemProxyConfiguration InitializeFileSystemProxy(FileSystemServer server, + FileSystemServerConfig config) + { + var saveDataIndexerManager = new SaveDataIndexerManager(server.Globals.Hos.Fs, Fs.SaveData.SaveIndexerId, + new ArrayPoolMemoryResource(), new SdHandleManager(), false); + + var programRegistryService = new ProgramRegistryServiceImpl(server); + + server.InitializeProgramRegistryImpl(programRegistryService); + + var baseStorageConfig = new BaseStorageServiceImpl.Configuration(); + baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator; + baseStorageConfig.GameCardStorageCreator = config.FsCreators.GameCardStorageCreator; + baseStorageConfig.FsServer = server; + baseStorageConfig.DeviceOperator = new ReferenceCountedDisposable(config.DeviceOperator); + var baseStorageService = new BaseStorageServiceImpl(in baseStorageConfig); + + var timeService = new TimeServiceImpl(server); + + var baseFsServiceConfig = new BaseFileSystemServiceImpl.Configuration(); + baseFsServiceConfig.BisFileSystemCreator = config.FsCreators.BuiltInStorageFileSystemCreator; + baseFsServiceConfig.GameCardFileSystemCreator = config.FsCreators.GameCardFileSystemCreator; + baseFsServiceConfig.SdCardFileSystemCreator = config.FsCreators.SdCardFileSystemCreator; + baseFsServiceConfig.BisWiperCreator = BisWiper.CreateWiper; + baseFsServiceConfig.FsServer = server; + var baseFsService = new BaseFileSystemServiceImpl(in baseFsServiceConfig); + + var accessFailureManagementServiceConfig = new AccessFailureManagementServiceImpl.Configuration(); + accessFailureManagementServiceConfig.FsServer = server; + + var accessFailureManagementService = + new AccessFailureManagementServiceImpl(in accessFailureManagementServiceConfig); + + var speedEmulationRange = + new InternalProgramIdRangeForSpeedEmulation(SpeedEmulationProgramIdMinimum, + SpeedEmulationProgramIdMaximum); + + var ncaFsServiceConfig = new NcaFileSystemServiceImpl.Configuration(); + ncaFsServiceConfig.BaseFsService = baseFsService; + ncaFsServiceConfig.HostFsCreator = config.FsCreators.HostFileSystemCreator; + ncaFsServiceConfig.TargetManagerFsCreator = config.FsCreators.TargetManagerFileSystemCreator; + ncaFsServiceConfig.PartitionFsCreator = config.FsCreators.PartitionFileSystemCreator; + ncaFsServiceConfig.RomFsCreator = config.FsCreators.RomFileSystemCreator; + ncaFsServiceConfig.StorageOnNcaCreator = config.FsCreators.StorageOnNcaCreator; + ncaFsServiceConfig.SubDirectoryFsCreator = config.FsCreators.SubDirectoryFileSystemCreator; + ncaFsServiceConfig.EncryptedFsCreator = config.FsCreators.EncryptedFileSystemCreator; + ncaFsServiceConfig.ProgramRegistryService = programRegistryService; + ncaFsServiceConfig.AccessFailureManagementService = accessFailureManagementService; + ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange; + ncaFsServiceConfig.FsServer = server; + + var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig, config.ExternalKeySet); + + var saveFsServiceConfig = new SaveDataFileSystemServiceImpl.Configuration(); + saveFsServiceConfig.BaseFsService = baseFsService; + saveFsServiceConfig.HostFsCreator = config.FsCreators.HostFileSystemCreator; + saveFsServiceConfig.TargetManagerFsCreator = config.FsCreators.TargetManagerFileSystemCreator; + saveFsServiceConfig.SaveFsCreator = config.FsCreators.SaveDataFileSystemCreator; + saveFsServiceConfig.EncryptedFsCreator = config.FsCreators.EncryptedFileSystemCreator; + saveFsServiceConfig.ProgramRegistryService = programRegistryService; + saveFsServiceConfig.ShouldCreateDirectorySaveData = () => true; + saveFsServiceConfig.SaveIndexerManager = saveDataIndexerManager; + saveFsServiceConfig.FsServer = server; + + var saveFsService = new SaveDataFileSystemServiceImpl(in saveFsServiceConfig); + + var statusReportServiceConfig = new StatusReportServiceImpl.Configuration(); + statusReportServiceConfig.NcaFsServiceImpl = ncaFsService; + statusReportServiceConfig.SaveFsServiceImpl = saveFsService; + statusReportServiceConfig.BufferManagerMemoryReport = null; + statusReportServiceConfig.ExpHeapMemoryReport = null; + statusReportServiceConfig.BufferPoolMemoryReport = null; + statusReportServiceConfig.GetPatrolAllocateCounts = null; + statusReportServiceConfig.MainThreadStackUsageReporter = new DummyStackUsageReporter(); + statusReportServiceConfig.IpcWorkerThreadStackUsageReporter = new DummyStackUsageReporter(); + statusReportServiceConfig.PipeLineWorkerThreadStackUsageReporter = new DummyStackUsageReporter(); + statusReportServiceConfig.FsServer = server; + + var statusReportService = new StatusReportServiceImpl(in statusReportServiceConfig); + + var accessLogServiceConfig = new AccessLogServiceImpl.Configuration(); + accessLogServiceConfig.MinimumProgramIdForSdCardLog = 0x0100000000003000; + accessLogServiceConfig.FsServer = server; + + var accessLogService = new AccessLogServiceImpl(in accessLogServiceConfig); + + var fspConfig = new FileSystemProxyConfiguration + { + FsCreatorInterfaces = config.FsCreators, + BaseStorageService = baseStorageService, + BaseFileSystemService = baseFsService, + NcaFileSystemService = ncaFsService, + SaveDataFileSystemService = saveFsService, + AccessFailureManagementService = accessFailureManagementService, + TimeService = timeService, + StatusReportService = statusReportService, + ProgramRegistryService = programRegistryService, + AccessLogService = accessLogService + }; + + server.InitializeFileSystemProxy(fspConfig); + return fspConfig; + } + + private static void InitializeFileSystemProxyServer(HorizonClient client, FileSystemServer server) + { + client.Sm.RegisterService(new FileSystemProxyService(server), "fsp-srv").IgnoreResult(); + client.Sm.RegisterService(new FileSystemProxyForLoaderService(server), "fsp-ldr").IgnoreResult(); + client.Sm.RegisterService(new ProgramRegistryService(server), "fsp-pr").IgnoreResult(); + } + + private class FileSystemProxyService : IServiceObject + { + private readonly FileSystemServer _server; + + public FileSystemProxyService(FileSystemServer server) + { + _server = server; + } + + public Result GetServiceObject(out object serviceObject) + { + serviceObject = _server.Impl.GetFileSystemProxyServiceObject(); + return Result.Success; + } + } + + private class FileSystemProxyForLoaderService : IServiceObject + { + private readonly FileSystemServer _server; + + public FileSystemProxyForLoaderService(FileSystemServer server) + { + _server = server; + } + + public Result GetServiceObject(out object serviceObject) + { + serviceObject = _server.Impl.GetFileSystemProxyForLoaderServiceObject(); + return Result.Success; + } + } + + private class ProgramRegistryService : IServiceObject + { + private readonly FileSystemServer _server; + + public ProgramRegistryService(FileSystemServer server) + { + _server = server; + } + + public Result GetServiceObject(out object serviceObject) + { + serviceObject = _server.Impl.GetProgramRegistryServiceObject(); + return Result.Success; + } + } + + private class DummyStackUsageReporter : IStackUsageReporter + { + public uint GetStackUsage() => 0; + } + } + + /// + /// Contains the configuration for creating a new . + /// + public class FileSystemServerConfig + { + /// + /// The used for creating filesystems. + /// + public FileSystemCreatorInterfaces FsCreators { get; set; } + + /// + /// An for managing the gamecard and SD card. + /// + public IDeviceOperator DeviceOperator { get; set; } + + /// + /// A keyset containing rights IDs and title keys. + /// If null, an empty set will be created. + /// + public ExternalKeySet ExternalKeySet { get; set; } + } +} diff --git a/src/LibHac/FsSrv/SaveDataFileSystemService.cs b/src/LibHac/FsSrv/SaveDataFileSystemService.cs index bdd801ef..37a124f2 100644 --- a/src/LibHac/FsSrv/SaveDataFileSystemService.cs +++ b/src/LibHac/FsSrv/SaveDataFileSystemService.cs @@ -403,7 +403,7 @@ namespace LibHac.FsSrv private Result DeleteSaveDataFileSystemBySaveDataSpaceIdCore(SaveDataSpaceId spaceId, ulong saveDataId) { - if (saveDataId != FileSystemServer.SaveIndexerId) + if (saveDataId != SaveData.SaveIndexerId) { SaveDataIndexerAccessor accessor = null; try @@ -449,7 +449,7 @@ namespace LibHac.FsSrv SaveDataSpaceId actualSpaceId; // Only the FS process may delete the save indexer's save data. - if (saveDataId == FileSystemServer.SaveIndexerId) + if (saveDataId == SaveData.SaveIndexerId) { if (!IsCurrentProcess(ProcessId)) return ResultFs.PermissionDenied.Log(); @@ -499,7 +499,7 @@ namespace LibHac.FsSrv // Remove the save data from the indexer. // The indexer doesn't track itself, so skip if deleting its save data. - if (saveDataId != FileSystemServer.SaveIndexerId) + if (saveDataId != SaveData.SaveIndexerId) { // accessor will never be null at this point rc = accessor!.Indexer.Delete(saveDataId); @@ -590,7 +590,7 @@ namespace LibHac.FsSrv // ReSharper disable once UnusedParameter.Global public Result UpdateSaveDataMacForDebug(SaveDataSpaceId spaceId, ulong saveDataId) { - if (saveDataId == FileSystemServer.SaveIndexerId) + if (saveDataId == SaveData.SaveIndexerId) return ResultFs.InvalidArgument.Log(); return ResultFs.NotImplemented.Log(); @@ -630,10 +630,10 @@ namespace LibHac.FsSrv try { // Add the new save data to the save indexer - if (attribute.StaticSaveDataId == FileSystemServer.SaveIndexerId) + if (attribute.StaticSaveDataId == SaveData.SaveIndexerId) { // The save indexer doesn't index itself - saveDataId = FileSystemServer.SaveIndexerId; + saveDataId = SaveData.SaveIndexerId; rc = ServiceImpl.DoesSaveDataEntityExist(out bool saveExists, creationInfo.SpaceId, saveDataId); if (rc.IsSuccess() && saveExists) @@ -755,7 +755,7 @@ namespace LibHac.FsSrv } // The indexer's save data isn't tracked, so we don't need to update its state. - if (attribute.StaticSaveDataId != FileSystemServer.SaveIndexerId) + if (attribute.StaticSaveDataId != SaveData.SaveIndexerId) { // accessor shouldn't ever be null, but checking makes the analyzers happy Abort.DoAbortUnless(accessor != null); @@ -778,7 +778,7 @@ namespace LibHac.FsSrv { DeleteSaveDataFileSystemCore(creationInfo.SpaceId, saveDataId, false).IgnoreResult(); - if (accessor != null && saveDataId != FileSystemServer.SaveIndexerId) + if (accessor != null && saveDataId != SaveData.SaveIndexerId) { rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId); @@ -994,7 +994,7 @@ namespace LibHac.FsSrv Result RemoveSaveIndexerEntry() { - if (tempSaveDataId == FileSystemServer.SaveIndexerId) + if (tempSaveDataId == SaveData.SaveIndexerId) return Result.Success; if (isStaticSaveDataId) diff --git a/src/LibHac/Horizon.cs b/src/LibHac/Horizon.cs index 0da47b47..fd4e2f0d 100644 --- a/src/LibHac/Horizon.cs +++ b/src/LibHac/Horizon.cs @@ -1,10 +1,8 @@ using System.Diagnostics; using System.Threading; -using LibHac.Bcat; using LibHac.Common; using LibHac.Diag; using LibHac.Fs.Shim; -using LibHac.FsSrv; using LibHac.FsSrv.Impl; using LibHac.Ncm; using LibHac.Os; @@ -20,14 +18,11 @@ namespace LibHac internal ServiceManager ServiceManager { get; } private HorizonClient LoaderClient { get; } - // long instead of ulong because the ulong Interlocked.Increment overload - // wasn't added until .NET 5 private ulong _currentInitialProcessId; private ulong _currentProcessId; - // Todo: Initialize with a configuration object - public Horizon(ITimeSpanGenerator timer, FileSystemServerConfig fsServerConfig) + public Horizon(ITimeSpanGenerator timer) { _currentProcessId = InitialProcessCountMax; @@ -35,11 +30,6 @@ namespace LibHac StartTick = Stopwatch.GetTimestamp(); ServiceManager = new ServiceManager(); - // ReSharper disable ObjectCreationAsStatement - new FileSystemServer(CreatePrivilegedHorizonClient(), fsServerConfig); - new BcatServer(CreateHorizonClient()); - // ReSharper restore ObjectCreationAsStatement - LoaderClient = CreatePrivilegedHorizonClient(); } diff --git a/src/LibHac/HorizonFactory.cs b/src/LibHac/HorizonFactory.cs new file mode 100644 index 00000000..9e465714 --- /dev/null +++ b/src/LibHac/HorizonFactory.cs @@ -0,0 +1,23 @@ +using LibHac.Bcat; +using LibHac.FsSrv; + +namespace LibHac +{ + public static class HorizonFactory + { + public static Horizon CreateWithFsConfig(ITimeSpanGenerator timer, FileSystemServerConfig fsServerConfig) + { + var horizon = new Horizon(timer); + + HorizonClient fsServerClient = horizon.CreatePrivilegedHorizonClient(); + var fsServer = new FileSystemServer(fsServerClient); + + FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, fsServerConfig); + + HorizonClient bcatServerClient = horizon.CreateHorizonClient(); + _ = new BcatServer(bcatServerClient); + + return horizon; + } + } +} diff --git a/tests/LibHac.Tests/Fs/FileSystemClientTests/FileSystemServerFactory.cs b/tests/LibHac.Tests/Fs/FileSystemClientTests/FileSystemServerFactory.cs index 132e5ada..abcba92d 100644 --- a/tests/LibHac.Tests/Fs/FileSystemClientTests/FileSystemServerFactory.cs +++ b/tests/LibHac.Tests/Fs/FileSystemClientTests/FileSystemServerFactory.cs @@ -20,7 +20,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests config.DeviceOperator = defaultObjects.DeviceOperator; config.ExternalKeySet = new ExternalKeySet(); - var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config); + Horizon horizon = LibHac.HorizonFactory.CreateWithFsConfig(new StopWatchTimeSpanGenerator(), config); HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient(); diff --git a/tests/LibHac.Tests/HorizonFactory.cs b/tests/LibHac.Tests/HorizonFactory.cs index cdfbca8d..85aca29e 100644 --- a/tests/LibHac.Tests/HorizonFactory.cs +++ b/tests/LibHac.Tests/HorizonFactory.cs @@ -18,7 +18,7 @@ namespace LibHac.Tests config.DeviceOperator = defaultObjects.DeviceOperator; config.ExternalKeySet = new ExternalKeySet(); - var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config); + Horizon horizon = LibHac.HorizonFactory.CreateWithFsConfig(new StopWatchTimeSpanGenerator(), config); return horizon; }