mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Move initialization code out of FileSystemServer
This commit is contained in:
parent
a94bb81c54
commit
e50078d939
8 changed files with 303 additions and 261 deletions
7
src/LibHac/Fs/SaveData.cs
Normal file
7
src/LibHac/Fs/SaveData.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace LibHac.Fs
|
||||||
|
{
|
||||||
|
public static class SaveData
|
||||||
|
{
|
||||||
|
public const ulong SaveIndexerId = 0x8000000000000000;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,24 +1,12 @@
|
||||||
using System;
|
using LibHac.FsSrv.Impl;
|
||||||
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.FsSrv.Storage;
|
||||||
using LibHac.Sm;
|
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
public class FileSystemServer
|
public class FileSystemServer
|
||||||
{
|
{
|
||||||
internal const ulong SaveIndexerId = 0x8000000000000000;
|
|
||||||
|
|
||||||
private const ulong SpeedEmulationProgramIdMinimum = 0x100000000000000;
|
|
||||||
private const ulong SpeedEmulationProgramIdMaximum = 0x100000000001FFF;
|
|
||||||
|
|
||||||
internal FileSystemServerGlobals Globals;
|
internal FileSystemServerGlobals Globals;
|
||||||
|
|
||||||
private HorizonClient Hos => Globals.Hos;
|
|
||||||
public FileSystemServerImpl Impl => new FileSystemServerImpl(this);
|
public FileSystemServerImpl Impl => new FileSystemServerImpl(this);
|
||||||
public StorageService Storage => new StorageService(this);
|
public StorageService Storage => new StorageService(this);
|
||||||
|
|
||||||
|
@ -26,236 +14,11 @@ namespace LibHac.FsSrv
|
||||||
/// Creates a new <see cref="FileSystemServer"/> and registers its services using the provided HOS client.
|
/// Creates a new <see cref="FileSystemServer"/> and registers its services using the provided HOS client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="horizonClient">The <see cref="HorizonClient"/> that will be used by this server.</param>
|
/// <param name="horizonClient">The <see cref="HorizonClient"/> that will be used by this server.</param>
|
||||||
/// <param name="config">The configuration for the created <see cref="FileSystemServer"/>.</param>
|
public FileSystemServer(HorizonClient horizonClient)
|
||||||
public FileSystemServer(HorizonClient horizonClient, 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");
|
|
||||||
|
|
||||||
Globals.Hos = horizonClient;
|
Globals.Hos = horizonClient;
|
||||||
Globals.InitMutex = new object();
|
Globals.InitMutex = new object();
|
||||||
|
|
||||||
FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config);
|
|
||||||
this.InitializeFileSystemProxy(fspConfig);
|
|
||||||
|
|
||||||
using ReferenceCountedDisposable<IFileSystemProxy> 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<IDeviceOperator>(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Contains the configuration for creating a new <see cref="FileSystemServer"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class FileSystemServerConfig
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The <see cref="FileSystemCreatorInterfaces"/> used for creating filesystems.
|
|
||||||
/// </summary>
|
|
||||||
public FileSystemCreatorInterfaces FsCreators { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An <see cref="IDeviceOperator"/> for managing the gamecard and SD card.
|
|
||||||
/// </summary>
|
|
||||||
public IDeviceOperator DeviceOperator { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A keyset containing rights IDs and title keys.
|
|
||||||
/// If null, an empty set will be created.
|
|
||||||
/// </summary>
|
|
||||||
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
|
internal struct FileSystemServerGlobals
|
||||||
|
@ -268,4 +31,20 @@ namespace LibHac.FsSrv
|
||||||
public AccessControlGlobals AccessControl;
|
public AccessControlGlobals AccessControl;
|
||||||
public StorageDeviceManagerFactoryGlobals StorageDeviceManagerFactory;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
243
src/LibHac/FsSrv/FileSystemServerInitializer.cs
Normal file
243
src/LibHac/FsSrv/FileSystemServerInitializer.cs
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a <see cref="FileSystemServer"/> with the provided <see cref="FileSystemServerConfig"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">The <see cref="HorizonClient"/> that <paramref name="server"/> was created with.</param>
|
||||||
|
/// <param name="server">The <see cref="FileSystemServer"/> to initialize.</param>
|
||||||
|
/// <param name="config">The config for initializing <paramref name="server"/>.</param>
|
||||||
|
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<IFileSystemProxy> 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<IDeviceOperator>(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the configuration for creating a new <see cref="FileSystemServer"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class FileSystemServerConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="FileSystemCreatorInterfaces"/> used for creating filesystems.
|
||||||
|
/// </summary>
|
||||||
|
public FileSystemCreatorInterfaces FsCreators { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="IDeviceOperator"/> for managing the gamecard and SD card.
|
||||||
|
/// </summary>
|
||||||
|
public IDeviceOperator DeviceOperator { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A keyset containing rights IDs and title keys.
|
||||||
|
/// If null, an empty set will be created.
|
||||||
|
/// </summary>
|
||||||
|
public ExternalKeySet ExternalKeySet { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -403,7 +403,7 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
private Result DeleteSaveDataFileSystemBySaveDataSpaceIdCore(SaveDataSpaceId spaceId, ulong saveDataId)
|
private Result DeleteSaveDataFileSystemBySaveDataSpaceIdCore(SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
{
|
{
|
||||||
if (saveDataId != FileSystemServer.SaveIndexerId)
|
if (saveDataId != SaveData.SaveIndexerId)
|
||||||
{
|
{
|
||||||
SaveDataIndexerAccessor accessor = null;
|
SaveDataIndexerAccessor accessor = null;
|
||||||
try
|
try
|
||||||
|
@ -449,7 +449,7 @@ namespace LibHac.FsSrv
|
||||||
SaveDataSpaceId actualSpaceId;
|
SaveDataSpaceId actualSpaceId;
|
||||||
|
|
||||||
// Only the FS process may delete the save indexer's save data.
|
// Only the FS process may delete the save indexer's save data.
|
||||||
if (saveDataId == FileSystemServer.SaveIndexerId)
|
if (saveDataId == SaveData.SaveIndexerId)
|
||||||
{
|
{
|
||||||
if (!IsCurrentProcess(ProcessId))
|
if (!IsCurrentProcess(ProcessId))
|
||||||
return ResultFs.PermissionDenied.Log();
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
@ -499,7 +499,7 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
// Remove the save data from the indexer.
|
// Remove the save data from the indexer.
|
||||||
// The indexer doesn't track itself, so skip if deleting its save data.
|
// 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
|
// accessor will never be null at this point
|
||||||
rc = accessor!.Indexer.Delete(saveDataId);
|
rc = accessor!.Indexer.Delete(saveDataId);
|
||||||
|
@ -590,7 +590,7 @@ namespace LibHac.FsSrv
|
||||||
// ReSharper disable once UnusedParameter.Global
|
// ReSharper disable once UnusedParameter.Global
|
||||||
public Result UpdateSaveDataMacForDebug(SaveDataSpaceId spaceId, ulong saveDataId)
|
public Result UpdateSaveDataMacForDebug(SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
{
|
{
|
||||||
if (saveDataId == FileSystemServer.SaveIndexerId)
|
if (saveDataId == SaveData.SaveIndexerId)
|
||||||
return ResultFs.InvalidArgument.Log();
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
|
||||||
return ResultFs.NotImplemented.Log();
|
return ResultFs.NotImplemented.Log();
|
||||||
|
@ -630,10 +630,10 @@ namespace LibHac.FsSrv
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Add the new save data to the save indexer
|
// 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
|
// The save indexer doesn't index itself
|
||||||
saveDataId = FileSystemServer.SaveIndexerId;
|
saveDataId = SaveData.SaveIndexerId;
|
||||||
rc = ServiceImpl.DoesSaveDataEntityExist(out bool saveExists, creationInfo.SpaceId, saveDataId);
|
rc = ServiceImpl.DoesSaveDataEntityExist(out bool saveExists, creationInfo.SpaceId, saveDataId);
|
||||||
|
|
||||||
if (rc.IsSuccess() && saveExists)
|
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.
|
// 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
|
// accessor shouldn't ever be null, but checking makes the analyzers happy
|
||||||
Abort.DoAbortUnless(accessor != null);
|
Abort.DoAbortUnless(accessor != null);
|
||||||
|
@ -778,7 +778,7 @@ namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
DeleteSaveDataFileSystemCore(creationInfo.SpaceId, saveDataId, false).IgnoreResult();
|
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);
|
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
||||||
|
|
||||||
|
@ -994,7 +994,7 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
Result RemoveSaveIndexerEntry()
|
Result RemoveSaveIndexerEntry()
|
||||||
{
|
{
|
||||||
if (tempSaveDataId == FileSystemServer.SaveIndexerId)
|
if (tempSaveDataId == SaveData.SaveIndexerId)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
if (isStaticSaveDataId)
|
if (isStaticSaveDataId)
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using LibHac.Bcat;
|
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Diag;
|
using LibHac.Diag;
|
||||||
using LibHac.Fs.Shim;
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSrv;
|
|
||||||
using LibHac.FsSrv.Impl;
|
using LibHac.FsSrv.Impl;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Os;
|
using LibHac.Os;
|
||||||
|
@ -20,14 +18,11 @@ namespace LibHac
|
||||||
internal ServiceManager ServiceManager { get; }
|
internal ServiceManager ServiceManager { get; }
|
||||||
private HorizonClient LoaderClient { 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 _currentInitialProcessId;
|
||||||
private ulong _currentProcessId;
|
private ulong _currentProcessId;
|
||||||
|
|
||||||
|
|
||||||
// Todo: Initialize with a configuration object
|
// Todo: Initialize with a configuration object
|
||||||
public Horizon(ITimeSpanGenerator timer, FileSystemServerConfig fsServerConfig)
|
public Horizon(ITimeSpanGenerator timer)
|
||||||
{
|
{
|
||||||
_currentProcessId = InitialProcessCountMax;
|
_currentProcessId = InitialProcessCountMax;
|
||||||
|
|
||||||
|
@ -35,11 +30,6 @@ namespace LibHac
|
||||||
StartTick = Stopwatch.GetTimestamp();
|
StartTick = Stopwatch.GetTimestamp();
|
||||||
ServiceManager = new ServiceManager();
|
ServiceManager = new ServiceManager();
|
||||||
|
|
||||||
// ReSharper disable ObjectCreationAsStatement
|
|
||||||
new FileSystemServer(CreatePrivilegedHorizonClient(), fsServerConfig);
|
|
||||||
new BcatServer(CreateHorizonClient());
|
|
||||||
// ReSharper restore ObjectCreationAsStatement
|
|
||||||
|
|
||||||
LoaderClient = CreatePrivilegedHorizonClient();
|
LoaderClient = CreatePrivilegedHorizonClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/LibHac/HorizonFactory.cs
Normal file
23
src/LibHac/HorizonFactory.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests
|
||||||
config.DeviceOperator = defaultObjects.DeviceOperator;
|
config.DeviceOperator = defaultObjects.DeviceOperator;
|
||||||
config.ExternalKeySet = new ExternalKeySet();
|
config.ExternalKeySet = new ExternalKeySet();
|
||||||
|
|
||||||
var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config);
|
Horizon horizon = LibHac.HorizonFactory.CreateWithFsConfig(new StopWatchTimeSpanGenerator(), config);
|
||||||
|
|
||||||
HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient();
|
HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace LibHac.Tests
|
||||||
config.DeviceOperator = defaultObjects.DeviceOperator;
|
config.DeviceOperator = defaultObjects.DeviceOperator;
|
||||||
config.ExternalKeySet = new ExternalKeySet();
|
config.ExternalKeySet = new ExternalKeySet();
|
||||||
|
|
||||||
var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config);
|
Horizon horizon = LibHac.HorizonFactory.CreateWithFsConfig(new StopWatchTimeSpanGenerator(), config);
|
||||||
|
|
||||||
return horizon;
|
return horizon;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue