mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-30 06:26:25 +02:00
Implement NGC service (#5681)
* Implement NGC service * Use raw byte arrays instead of string for _wordSeparators * Silence IDE0230 for _wordSeparators * Try to silence warning about _rangeValuesCount not being read on SparseSet * Make AcType enum private * Add abstract methods and one TODO that I forgot * PR feedback * More PR feedback * More PR feedback
This commit is contained in:
parent
4bd2ca3f0d
commit
01c2b8097c
44 changed files with 4630 additions and 4 deletions
|
@ -327,8 +327,10 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
private void StartNewServices()
|
||||
{
|
||||
HorizonFsClient fsClient = new(this);
|
||||
|
||||
ServiceTable = new ServiceTable();
|
||||
var services = ServiceTable.GetServices(new HorizonOptions(Device.Configuration.IgnoreMissingServices, LibHacHorizonManager.BcatClient));
|
||||
var services = ServiceTable.GetServices(new HorizonOptions(Device.Configuration.IgnoreMissingServices, LibHacHorizonManager.BcatClient, fsClient));
|
||||
|
||||
foreach (var service in services)
|
||||
{
|
||||
|
|
119
src/Ryujinx.HLE/HOS/HorizonFsClient.cs
Normal file
119
src/Ryujinx.HLE/HOS/HorizonFsClient.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.Horizon;
|
||||
using Ryujinx.Horizon.Common;
|
||||
using Ryujinx.Horizon.Sdk.Fs;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
|
||||
namespace Ryujinx.HLE.HOS
|
||||
{
|
||||
class HorizonFsClient : IFsClient
|
||||
{
|
||||
private readonly Horizon _system;
|
||||
private readonly LibHac.Fs.FileSystemClient _fsClient;
|
||||
private readonly ConcurrentDictionary<string, LocalStorage> _mountedStorages;
|
||||
|
||||
public HorizonFsClient(Horizon system)
|
||||
{
|
||||
_system = system;
|
||||
_fsClient = _system.LibHacHorizonManager.FsClient.Fs;
|
||||
_mountedStorages = new();
|
||||
}
|
||||
|
||||
public void CloseFile(FileHandle handle)
|
||||
{
|
||||
_fsClient.CloseFile((LibHac.Fs.FileHandle)handle.Value);
|
||||
}
|
||||
|
||||
public Result GetFileSize(out long size, FileHandle handle)
|
||||
{
|
||||
return _fsClient.GetFileSize(out size, (LibHac.Fs.FileHandle)handle.Value).ToHorizonResult();
|
||||
}
|
||||
|
||||
public Result MountSystemData(string mountName, ulong dataId)
|
||||
{
|
||||
string contentPath = _system.ContentManager.GetInstalledContentPath(dataId, StorageId.BuiltInSystem, NcaContentType.PublicData);
|
||||
string installPath = VirtualFileSystem.SwitchPathToSystemPath(contentPath);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(installPath))
|
||||
{
|
||||
string ncaPath = installPath;
|
||||
|
||||
if (File.Exists(ncaPath))
|
||||
{
|
||||
LocalStorage ncaStorage = null;
|
||||
|
||||
try
|
||||
{
|
||||
ncaStorage = new LocalStorage(ncaPath, FileAccess.Read, FileMode.Open);
|
||||
|
||||
Nca nca = new(_system.KeySet, ncaStorage);
|
||||
|
||||
using var ncaFileSystem = nca.OpenFileSystem(NcaSectionType.Data, _system.FsIntegrityCheckLevel);
|
||||
using var ncaFsRef = new UniqueRef<IFileSystem>(ncaFileSystem);
|
||||
|
||||
Result result = _fsClient.Register(mountName.ToU8Span(), ref ncaFsRef.Ref).ToHorizonResult();
|
||||
if (result.IsFailure)
|
||||
{
|
||||
ncaStorage.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
_mountedStorages.TryAdd(mountName, ncaStorage);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (HorizonResultException ex)
|
||||
{
|
||||
ncaStorage?.Dispose();
|
||||
|
||||
return ex.ResultValue.ToHorizonResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Return correct result here, this is likely wrong.
|
||||
|
||||
return LibHac.Fs.ResultFs.TargetNotFound.Handle().ToHorizonResult();
|
||||
}
|
||||
|
||||
public Result OpenFile(out FileHandle handle, string path, OpenMode openMode)
|
||||
{
|
||||
var result = _fsClient.OpenFile(out var libhacHandle, path.ToU8Span(), (LibHac.Fs.OpenMode)openMode);
|
||||
handle = new(libhacHandle);
|
||||
|
||||
return result.ToHorizonResult();
|
||||
}
|
||||
|
||||
public Result QueryMountSystemDataCacheSize(out long size, ulong dataId)
|
||||
{
|
||||
// TODO.
|
||||
|
||||
size = 0;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ReadFile(FileHandle handle, long offset, Span<byte> destination)
|
||||
{
|
||||
return _fsClient.ReadFile((LibHac.Fs.FileHandle)handle.Value, offset, destination).ToHorizonResult();
|
||||
}
|
||||
|
||||
public void Unmount(string mountName)
|
||||
{
|
||||
if (_mountedStorages.TryRemove(mountName, out LocalStorage ncaStorage))
|
||||
{
|
||||
ncaStorage.Dispose();
|
||||
}
|
||||
|
||||
_fsClient.Unmount(mountName.ToU8Span());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue