Start refactoring IPC objects (started with IFile and IFileSystem)

This commit is contained in:
gdkchan 2018-02-09 18:05:20 -03:00
parent ccc9ce1908
commit 9929ecf3ba
6 changed files with 89 additions and 51 deletions

View file

@ -10,8 +10,6 @@ namespace Ryujinx.OsHle.Ipc
{
static class IpcHandler
{
private delegate long ServiceProcessRequest(ServiceCtx Context);
private static Dictionary<(string, int), ServiceProcessRequest> ServiceCmds =
new Dictionary<(string, int), ServiceProcessRequest>()
{
@ -141,15 +139,6 @@ namespace Ryujinx.OsHle.Ipc
{ (typeof(AudIAudioOut), 7), AudIAudioOut.AppendAudioOutBuffer_ex },
{ (typeof(AudIAudioOut), 8), AudIAudioOut.GetReleasedAudioOutBuffer_ex },
//IFile
{ (typeof(FspSrvIFile), 0), FspSrvIFile.Read },
{ (typeof(FspSrvIFile), 1), FspSrvIFile.Write },
//IFileSystem
{ (typeof(FspSrvIFileSystem), 7), FspSrvIFileSystem.GetEntryType },
{ (typeof(FspSrvIFileSystem), 8), FspSrvIFileSystem.OpenFile },
{ (typeof(FspSrvIFileSystem), 10), FspSrvIFileSystem.Commit },
//IStorage
{ (typeof(FspSrvIStorage), 0), FspSrvIStorage.Read },
@ -221,15 +210,24 @@ namespace Ryujinx.OsHle.Ipc
if (Obj is HDomain)
{
DbgServiceName = $"{ServiceName} {CmdId}";
ServiceCmds.TryGetValue((ServiceName, CmdId), out ProcReq);
DbgServiceName = $"{ServiceName} {ProcReq?.Method.Name ?? CmdId.ToString()}";
}
else if (Obj != null)
{
DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {CmdId}";
if (Obj is IIpcInterface IpcObj)
{
IpcObj.Commands.TryGetValue(CmdId, out ProcReq);
}
else
{
//Note: Once all objects starts implementing IIpcInterface,
//ObjectCmds can be removed completely.
ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
}
ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {ProcReq?.Method.Name ?? CmdId.ToString()}";
}
}
else if (Request.DomCmd == IpcDomCmd.DeleteObj)
@ -248,17 +246,26 @@ namespace Ryujinx.OsHle.Ipc
if (Session is HSessionObj)
{
object Obj = ((HSessionObj)Session).Obj;
object Obj = ((HSessionObj)Session).Obj;
DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {CmdId}";
if (Obj is IIpcInterface IpcObj)
{
IpcObj.Commands.TryGetValue(CmdId, out ProcReq);
}
else
{
//Note: Once all objects starts implementing IIpcInterface,
//ObjectCmds can be removed completely.
ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
}
ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {ProcReq?.Method.Name ?? CmdId.ToString()}";
}
else
{
DbgServiceName = $"{ServiceName} {CmdId}";
ServiceCmds.TryGetValue((ServiceName, CmdId), out ProcReq);
DbgServiceName = $"{ServiceName} {ProcReq?.Method.Name ?? CmdId.ToString()}";
}
}

View file

@ -0,0 +1,4 @@
namespace Ryujinx.OsHle.Ipc
{
delegate long ServiceProcessRequest(ServiceCtx Context);
}

View file

@ -1,23 +1,32 @@
using ChocolArm64.Memory;
using Ryujinx.OsHle.Ipc;
using System;
using System.Collections.Generic;
using System.IO;
namespace Ryujinx.OsHle.Objects
namespace Ryujinx.OsHle.Objects.FspSrv
{
class FspSrvIFile : IDisposable
class IFile : IIpcInterface, IDisposable
{
public Stream BaseStream { get; private set; }
private Dictionary<int, ServiceProcessRequest> m_Commands;
public FspSrvIFile(Stream BaseStream)
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private Stream BaseStream;
public IFile(Stream BaseStream)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 0, Read },
{ 1, Write }
};
this.BaseStream = BaseStream;
}
public static long Read(ServiceCtx Context)
public long Read(ServiceCtx Context)
{
FspSrvIFile File = Context.GetObject<FspSrvIFile>();
long Position = Context.Request.ReceiveBuff[0].Position;
long Zero = Context.RequestData.ReadInt64();
@ -26,7 +35,7 @@ namespace Ryujinx.OsHle.Objects
byte[] Data = new byte[Size];
int ReadSize = File.BaseStream.Read(Data, 0, (int)Size);
int ReadSize = BaseStream.Read(Data, 0, (int)Size);
AMemoryHelper.WriteBytes(Context.Memory, Position, Data);
@ -38,10 +47,8 @@ namespace Ryujinx.OsHle.Objects
return 0;
}
public static long Write(ServiceCtx Context)
public long Write(ServiceCtx Context)
{
FspSrvIFile File = Context.GetObject<FspSrvIFile>();
long Position = Context.Request.SendBuff[0].Position;
long Zero = Context.RequestData.ReadInt64();
@ -50,8 +57,8 @@ namespace Ryujinx.OsHle.Objects
byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, (int)Size);
File.BaseStream.Seek(Offset, SeekOrigin.Begin);
File.BaseStream.Write(Data, 0, (int)Size);
BaseStream.Seek(Offset, SeekOrigin.Begin);
BaseStream.Write(Data, 0, (int)Size);
return 0;
}

View file

@ -1,28 +1,39 @@
using ChocolArm64.Memory;
using Ryujinx.OsHle.Ipc;
using System.Collections.Generic;
using System.IO;
using static Ryujinx.OsHle.Objects.ObjHelper;
namespace Ryujinx.OsHle.Objects
namespace Ryujinx.OsHle.Objects.FspSrv
{
class FspSrvIFileSystem
class IFileSystem : IIpcInterface
{
public string FilePath { get; private set; }
private Dictionary<int, ServiceProcessRequest> m_Commands;
public FspSrvIFileSystem(string Path)
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private string Path;
public IFileSystem(string Path)
{
this.FilePath = Path;
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 7, GetEntryType },
{ 8, OpenFile },
{ 10, Commit },
};
this.Path = Path;
}
public static long GetEntryType(ServiceCtx Context)
public long GetEntryType(ServiceCtx Context)
{
FspSrvIFileSystem FileSystem = Context.GetObject<FspSrvIFileSystem>();
long Position = Context.Request.PtrBuff[0].Position;
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position);
string FileName = Context.Ns.VFs.GetFullPath(FileSystem.FilePath, Name);
string FileName = Context.Ns.VFs.GetFullPath(Path, Name);
if (FileName == null)
{
@ -37,17 +48,15 @@ namespace Ryujinx.OsHle.Objects
return 0;
}
public static long OpenFile(ServiceCtx Context)
public long OpenFile(ServiceCtx Context)
{
FspSrvIFileSystem FileSystem = Context.GetObject<FspSrvIFileSystem>();
long Position = Context.Request.PtrBuff[0].Position;
int FilterFlags = Context.RequestData.ReadInt32();
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position);
string FileName = Context.Ns.VFs.GetFullPath(FileSystem.FilePath, Name);
string FileName = Context.Ns.VFs.GetFullPath(Path, Name);
if (FileName == null)
{
@ -57,12 +66,12 @@ namespace Ryujinx.OsHle.Objects
FileStream Stream = new FileStream(FileName, FileMode.OpenOrCreate);
MakeObject(Context, new FspSrvIFile(Stream));
MakeObject(Context, new IFile(Stream));
return 0;
}
public static long Commit(ServiceCtx Context)
public long Commit(ServiceCtx Context)
{
return 0;
}

View file

@ -0,0 +1,10 @@
using Ryujinx.OsHle.Ipc;
using System.Collections.Generic;
namespace Ryujinx.OsHle.Objects
{
interface IIpcInterface
{
IReadOnlyDictionary<int, ServiceProcessRequest> Commands { get; }
}
}

View file

@ -1,4 +1,5 @@
using Ryujinx.OsHle.Objects;
using Ryujinx.OsHle.Objects.FspSrv;
using static Ryujinx.OsHle.Objects.ObjHelper;
@ -13,14 +14,14 @@ namespace Ryujinx.OsHle.Services
public static long FspSrvMountSdCard(ServiceCtx Context)
{
MakeObject(Context, new FspSrvIFileSystem(Context.Ns.VFs.GetSdCardPath()));
MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetSdCardPath()));
return 0;
}
public static long FspSrvMountSaveData(ServiceCtx Context)
{
MakeObject(Context, new FspSrvIFileSystem(Context.Ns.VFs.GetGameSavesPath()));
MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetGameSavesPath()));
return 0;
}