From dadc01943965c777f450e34b2555269dc57b804d Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Tue, 2 Feb 2021 21:11:51 -0700 Subject: [PATCH] Use globals in more places Adds globals for FileSystemProxyImpl, ProgramRegistryImpl, AccessControl and StorageDeviceManagerFactory --- src/LibHac/Fs/Shim/CustomStorage.cs | 15 ++- .../Creators/EncryptedFileSystemCreator.cs | 22 +---- ...tors.cs => FileSystemCreatorInterfaces.cs} | 2 +- .../Creators/IEncryptedFileSystemCreator.cs | 7 +- src/LibHac/FsSrv/DefaultFsServerObjects.cs | 4 +- .../FsSrv/FileSystemProxyConfiguration.cs | 2 +- src/LibHac/FsSrv/FileSystemProxyCoreImpl.cs | 97 +++++++++++-------- src/LibHac/FsSrv/FileSystemProxyImpl.cs | 71 +++++++++++--- src/LibHac/FsSrv/FileSystemServer.cs | 75 +++++--------- src/LibHac/FsSrv/Impl/AccessControl.cs | 28 ++++-- .../FsSrv/Impl/IDeviceEventSimulator.cs | 16 +-- src/LibHac/FsSrv/ProgramRegistryImpl.cs | 36 ++++--- src/LibHac/FsSrv/Storage/SdCardService.cs | 2 +- .../Storage/StorageDeviceManagerFactory.cs | 39 +++++++- 14 files changed, 243 insertions(+), 173 deletions(-) rename src/LibHac/FsSrv/Creators/{FileSystemCreators.cs => FileSystemCreatorInterfaces.cs} (96%) diff --git a/src/LibHac/Fs/Shim/CustomStorage.cs b/src/LibHac/Fs/Shim/CustomStorage.cs index cd92c356..aa3d2de5 100644 --- a/src/LibHac/Fs/Shim/CustomStorage.cs +++ b/src/LibHac/Fs/Shim/CustomStorage.cs @@ -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 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' + }; } } diff --git a/src/LibHac/FsSrv/Creators/EncryptedFileSystemCreator.cs b/src/LibHac/FsSrv/Creators/EncryptedFileSystemCreator.cs index 923bf0dd..c3d2798c 100644 --- a/src/LibHac/FsSrv/Creators/EncryptedFileSystemCreator.cs +++ b/src/LibHac/FsSrv/Creators/EncryptedFileSystemCreator.cs @@ -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 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 encryptedFileSystem, ReferenceCountedDisposable baseFileSystem, EncryptedFsKeyId keyId, in EncryptionSeed encryptionSeed) { diff --git a/src/LibHac/FsSrv/Creators/FileSystemCreators.cs b/src/LibHac/FsSrv/Creators/FileSystemCreatorInterfaces.cs similarity index 96% rename from src/LibHac/FsSrv/Creators/FileSystemCreators.cs rename to src/LibHac/FsSrv/Creators/FileSystemCreatorInterfaces.cs index 22ece1f3..def57d17 100644 --- a/src/LibHac/FsSrv/Creators/FileSystemCreators.cs +++ b/src/LibHac/FsSrv/Creators/FileSystemCreatorInterfaces.cs @@ -1,6 +1,6 @@ namespace LibHac.FsSrv.Creators { - public class FileSystemCreators + public class FileSystemCreatorInterfaces { public IRomFileSystemCreator RomFileSystemCreator { get; set; } public IPartitionFileSystemCreator PartitionFileSystemCreator { get; set; } diff --git a/src/LibHac/FsSrv/Creators/IEncryptedFileSystemCreator.cs b/src/LibHac/FsSrv/Creators/IEncryptedFileSystemCreator.cs index 0db77318..5262f4b6 100644 --- a/src/LibHac/FsSrv/Creators/IEncryptedFileSystemCreator.cs +++ b/src/LibHac/FsSrv/Creators/IEncryptedFileSystemCreator.cs @@ -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 encryptionSeed); - Result Create(out ReferenceCountedDisposable encryptedFileSystem, ReferenceCountedDisposable baseFileSystem, EncryptedFsKeyId keyId, in EncryptionSeed encryptionSeed); diff --git a/src/LibHac/FsSrv/DefaultFsServerObjects.cs b/src/LibHac/FsSrv/DefaultFsServerObjects.cs index d3658800..d1642473 100644 --- a/src/LibHac/FsSrv/DefaultFsServerObjects.cs +++ b/src/LibHac/FsSrv/DefaultFsServerObjects.cs @@ -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(); diff --git a/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs b/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs index 566b1f2d..f6a04ea5 100644 --- a/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs +++ b/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs @@ -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; } diff --git a/src/LibHac/FsSrv/FileSystemProxyCoreImpl.cs b/src/LibHac/FsSrv/FileSystemProxyCoreImpl.cs index 2713afbf..ae25841f 100644 --- a/src/LibHac/FsSrv/FileSystemProxyCoreImpl.cs +++ b/src/LibHac/FsSrv/FileSystemProxyCoreImpl.cs @@ -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 fileSystem, @@ -34,44 +31,60 @@ namespace LibHac.FsSrv { fileSystem = default; - switch (storageId) + ReferenceCountedDisposable tempFs = null; + ReferenceCountedDisposable encryptedFs = null; + try { - case CustomStorageId.SdCard: + Span path = stackalloc byte[0x40]; + + switch (storageId) { - Result rc = FsCreators.SdCardFileSystemCreator.Create(out IFileSystem sdFs, false); - if (rc.IsFailure()) return rc; + case CustomStorageId.SdCard: + { + 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); - if (rc.IsFailure()) return rc; + rc = Utility.WrapSubDirectory(out tempFs, ref tempFs, new U8Span(path), true); + if (rc.IsFailure()) return rc; - rc = FsCreators.EncryptedFileSystemCreator.Create(out IFileSystem encryptedFs, subFs, - EncryptedFsKeyId.CustomStorage, SdEncryptionSeed); - if (rc.IsFailure()) return rc; + rc = FsCreators.EncryptedFileSystemCreator.Create(out encryptedFs, tempFs, + EncryptedFsKeyId.CustomStorage, SdEncryptionSeed); + if (rc.IsFailure()) return rc; - fileSystem = new ReferenceCountedDisposable(encryptedFs); - return Result.Success; + return Result.Success; + } + case CustomStorageId.System: + { + Result rc = BaseFileSystemService.OpenBisFileSystem(out tempFs, U8Span.Empty, + BisPartitionId.User); + if (rc.IsFailure()) return rc; + + U8Span customStorageDir = CustomStorage.GetCustomStorageDirectoryName(CustomStorageId.System); + var sb = new U8StringBuilder(path); + sb.Append((byte)'/') + .Append(customStorageDir); + + rc = Utility.WrapSubDirectory(out tempFs, ref tempFs, new U8Span(path), true); + if (rc.IsFailure()) return rc; + + fileSystem = Shared.Move(ref tempFs); + return Result.Success; + } + default: + return ResultFs.InvalidArgument.Log(); } - case CustomStorageId.System: - { - Result rc = FsCreators.BuiltInStorageFileSystemCreator.Create(out IFileSystem userFs, string.Empty, - BisPartitionId.User); - if (rc.IsFailure()) return rc; - - string customStorageDir = CustomStorage.GetCustomStorageDirectoryName(CustomStorageId.System); - string subDirName = $"/{customStorageDir}"; - - rc = Util.CreateSubFileSystem(out IFileSystem subFs, userFs, subDirName, true); - if (rc.IsFailure()) return rc; - - // Todo: Get shared object from earlier functions - fileSystem = new ReferenceCountedDisposable(subFs); - return Result.Success; - } - default: - return ResultFs.InvalidArgument.Log(); + } + finally + { + tempFs?.Dispose(); + encryptedFs?.Dispose(); } } @@ -127,7 +140,7 @@ namespace LibHac.FsSrv public Result SetSdCardEncryptionSeed(in EncryptionSeed seed) { - seed.Value.CopyTo(SdEncryptionSeed); + SdEncryptionSeed = seed; return Result.Success; } } diff --git a/src/LibHac/FsSrv/FileSystemProxyImpl.cs b/src/LibHac/FsSrv/FileSystemProxyImpl.cs index 46c6201c..d3c70b0c 100644 --- a/src/LibHac/FsSrv/FileSystemProxyImpl.cs +++ b/src/LibHac/FsSrv/FileSystemProxyImpl.cs @@ -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; + } + public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader { + private FileSystemServer FsServer { get; } + private ref FileSystemProxyImplGlobals Globals => ref FsServer.Globals.FileSystemProxyImpl; + private FileSystemProxyCoreImpl FsProxyCore { get; } private ReferenceCountedDisposable NcaFsService { get; set; } private ReferenceCountedDisposable 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 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) diff --git a/src/LibHac/FsSrv/FileSystemServer.cs b/src/LibHac/FsSrv/FileSystemServer.cs index ee619311..9b5ca8b3 100644 --- a/src/LibHac/FsSrv/FileSystemServer.cs +++ b/src/LibHac/FsSrv/FileSystemServer.cs @@ -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); /// The client instance to be used for internal operations like save indexer access. - 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; /// /// Creates a new 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 { /// - /// The used for creating filesystems. + /// The used for creating filesystems. /// - public FileSystemCreators FsCreators { get; set; } + public FileSystemCreatorInterfaces FsCreators { get; set; } /// /// An 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; } } diff --git a/src/LibHac/FsSrv/Impl/AccessControl.cs b/src/LibHac/FsSrv/Impl/AccessControl.cs index 4e166f06..98a9caa9 100644 --- a/src/LibHac/FsSrv/Impl/AccessControl.cs +++ b/src/LibHac/FsSrv/Impl/AccessControl.cs @@ -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; + } + /// /// Controls access to FS resources for a single process. /// @@ -17,15 +30,16 @@ namespace LibHac.FsSrv.Impl ///
Based on FS 10.0.0 (nnSdk 10.4.0) public class AccessControl { - private AccessControlBits? AccessBits { get; } + private FileSystemServer FsServer { get; } + private ref AccessControlGlobals Globals => ref FsServer.Globals.AccessControl; + + private Optional AccessBits { get; } private LinkedList ContentOwners { get; } = new LinkedList(); private LinkedList SaveDataOwners { get; } = new LinkedList(); - private FileSystemServer FsServer { get; } - public AccessControl(FileSystemServer fsServer, ReadOnlySpan accessControlData, - ReadOnlySpan accessControlDescriptor) : - this(fsServer, accessControlData, accessControlDescriptor, GetAccessBitsMask(fsServer.IsDebugMode)) + ReadOnlySpan accessControlDescriptor) : this(fsServer, accessControlData, accessControlDescriptor, + GetAccessBitsMask(fsServer.Globals.AccessControl.DebugFlag)) { } public AccessControl(FileSystemServer fsServer, ReadOnlySpan 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: diff --git a/src/LibHac/FsSrv/Impl/IDeviceEventSimulator.cs b/src/LibHac/FsSrv/Impl/IDeviceEventSimulator.cs index a10099d8..3863f262 100644 --- a/src/LibHac/FsSrv/Impl/IDeviceEventSimulator.cs +++ b/src/LibHac/FsSrv/Impl/IDeviceEventSimulator.cs @@ -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; } } diff --git a/src/LibHac/FsSrv/ProgramRegistryImpl.cs b/src/LibHac/FsSrv/ProgramRegistryImpl.cs index 04bd8bf0..4e705d32 100644 --- a/src/LibHac/FsSrv/ProgramRegistryImpl.cs +++ b/src/LibHac/FsSrv/ProgramRegistryImpl.cs @@ -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; + } + /// /// Used to add, remove or access the Program Registry. /// @@ -16,21 +30,15 @@ namespace LibHac.FsSrv ///
Based on FS 10.0.0 (nnSdk 10.4.0) 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; } /// : The operation was successful.
@@ -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); } /// public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId) { - return _registryService.GetProgramInfo(out programInfo, processId); + return Globals.ServiceImpl.GetProgramInfo(out programInfo, processId); } /// public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId) { - return _registryService.GetProgramInfoByProgramId(out programInfo, programId); + return Globals.ServiceImpl.GetProgramInfoByProgramId(out programInfo, programId); } /// diff --git a/src/LibHac/FsSrv/Storage/SdCardService.cs b/src/LibHac/FsSrv/Storage/SdCardService.cs index a6e4801d..258c7627 100644 --- a/src/LibHac/FsSrv/Storage/SdCardService.cs +++ b/src/LibHac/FsSrv/Storage/SdCardService.cs @@ -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); diff --git a/src/LibHac/FsSrv/Storage/StorageDeviceManagerFactory.cs b/src/LibHac/FsSrv/Storage/StorageDeviceManagerFactory.cs index e2c86b0e..0a284f31 100644 --- a/src/LibHac/FsSrv/Storage/StorageDeviceManagerFactory.cs +++ b/src/LibHac/FsSrv/Storage/StorageDeviceManagerFactory.cs @@ -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 + { + /// + /// Sets the to be used by the . + /// Calling this method more than once will do nothing. + /// + /// The Storage instance to use. + /// The to be used by this Storage instance. + 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 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; + } } }