diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index f0a6404f8f..938e90259c 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -1,5 +1,6 @@ using LibHac; using LibHac.Fs; +using LibHac.FsService; using LibHac.FsSystem; using LibHac.FsSystem.NcaUtils; using LibHac.Spl; @@ -118,6 +119,9 @@ namespace Ryujinx.HLE.HOS internal long HidBaseAddress { get; private set; } + internal FileSystemServer FsServer { get; private set; } + internal EmulatedGameCard GameCard { get; private set; } + public Horizon(Switch device) { ControlData = new Nacp(); @@ -230,6 +234,20 @@ namespace Ryujinx.HLE.HOS // FIXME: TimeZone shoud be init here but it's actually done in ContentManager TimeServiceManager.Instance.SetupEphemeralNetworkSystemClock(); + + LocalFileSystem baseFs = new LocalFileSystem(device.FileSystem.GetBasePath()); + DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(baseFs, KeySet); + + GameCard = fsServerObjects.GameCard; + + FileSystemServerConfig fsServerConfig = new FileSystemServerConfig + { + FsCreators = fsServerObjects.FsCreators, + DeviceOperator = fsServerObjects.DeviceOperator, + ExternalKeySet = KeySet.ExternalKeySet + }; + + FsServer = new FileSystemServer(fsServerConfig); } public void LoadCart(string exeFsDir, string romFsFile = null) diff --git a/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs new file mode 100644 index 0000000000..b52169d23c --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs @@ -0,0 +1,37 @@ +using LibHac; +using LibHac.FsService; + +namespace Ryujinx.HLE.HOS.Services.Fs +{ + class IDeviceOperator : IpcService + { + private LibHac.FsService.IDeviceOperator _baseOperator; + + public IDeviceOperator(LibHac.FsService.IDeviceOperator baseOperator) + { + _baseOperator = baseOperator; + } + + [Command(200)] + // IsGameCardInserted() -> b8 is_inserted + public ResultCode IsGameCardInserted(ServiceCtx context) + { + Result rc = _baseOperator.IsGameCardInserted(out bool isInserted); + + context.ResponseData.Write(isInserted); + + return (ResultCode)rc.Value; + } + + [Command(202)] + // GetGameCardHandle() -> u32 gamecard_handle + public ResultCode GetGameCardHandle(ServiceCtx context) + { + Result rc = _baseOperator.GetGameCardHandle(out GameCardHandle handle); + + context.ResponseData.Write(handle.Value); + + return (ResultCode)rc.Value; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index c362834ced..6a5097432e 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -1,4 +1,6 @@ using LibHac; +using LibHac.Fs; +using LibHac.FsService; using LibHac.FsSystem; using LibHac.FsSystem.NcaUtils; using Ryujinx.Common.Logging; @@ -14,7 +16,12 @@ namespace Ryujinx.HLE.HOS.Services.Fs [Service("fsp-srv")] class IFileSystemProxy : IpcService { - public IFileSystemProxy(ServiceCtx context) { } + private LibHac.FsService.IFileSystemProxy _baseFileSystemProxy; + + public IFileSystemProxy(ServiceCtx context) + { + _baseFileSystemProxy = context.Device.System.FsServer.CreateFileSystemProxyService(); + } [Command(1)] // Initialize(u64, pid) @@ -125,6 +132,21 @@ namespace Ryujinx.HLE.HOS.Services.Fs return ResultCode.Success; } + [Command(30)] + // OpenGameCardStorage(u32, u32) -> object + public ResultCode OpenGameCardStorage(ServiceCtx context) + { + GameCardHandle handle = new GameCardHandle(context.RequestData.ReadInt32()); + GameCardPartitionRaw partitionId = (GameCardPartitionRaw) context.RequestData.ReadInt32(); + + Result rc = _baseFileSystemProxy.OpenGameCardStorage(out LibHac.Fs.IStorage storage, handle, partitionId); + if (rc.IsFailure()) return (ResultCode)rc.Value; + + MakeObject(context, new FileSystemProxy.IStorage(storage)); + + return ResultCode.Success; + } + [Command(51)] // OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object saveDataFs public ResultCode OpenSaveDataFileSystem(ServiceCtx context) @@ -246,6 +268,18 @@ namespace Ryujinx.HLE.HOS.Services.Fs return ResultCode.Success; } + [Command(400)] + // OpenDataStorageByCurrentProcess() -> object dataStorage + public ResultCode OpenDeviceOperator(ServiceCtx context) + { + Result rc = _baseFileSystemProxy.OpenDeviceOperator(out LibHac.FsService.IDeviceOperator deviceOperator); + if (rc.IsFailure()) return (ResultCode)rc.Value; + + MakeObject(context, new IDeviceOperator(deviceOperator)); + + return 0; + } + [Command(1005)] // GetGlobalAccessLogMode() -> u32 logMode public ResultCode GetGlobalAccessLogMode(ServiceCtx context)