aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-08-16 20:47:36 -0300
committerGitHub <noreply@github.com>2018-08-16 20:47:36 -0300
commit521751795a1c97c0d97f6f8904a3be69b13d3a9d (patch)
tree942a05899c40e2de6d92a38b93a494bd96ee64b8 /Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
parent182d716867ae477c2b15a5332430dc2641fa1cc3 (diff)
Code style fixes and nits on the HLE project (#355)
* Some style fixes and nits on ITimeZoneService * Remove some unneeded usings * Remove the Ryujinx.HLE.OsHle.Handles namespace * Remove hbmenu automatic load on process exit * Rename Ns to Device, rename Os to System, rename SystemState to State * Move Exceptions and Utilities out of OsHle * Rename OsHle to HOS * Rename OsHle folder to HOS * IManagerDisplayService and ISystemDisplayService style fixes * BsdError shouldn't be public * Add a empty new line before using static * Remove unused file * Some style fixes on NPDM * Exit gracefully when the application is closed * Code style fixes on IGeneralService * Add 0x prefix on values printed as hex * Small improvements on finalization code * Move ProcessId and ThreadId out of AThreadState * Rename VFs to FileSystem * FsAccessHeader shouldn't be public. Also fix file names casing * More case changes on NPDM * Remove unused files * Move using to the correct place on NPDM * Use properties on KernelAccessControlMmio * Address PR feedback
Diffstat (limited to 'Ryujinx.HLE/HOS/Ipc/IpcMessage.cs')
-rw-r--r--Ryujinx.HLE/HOS/Ipc/IpcMessage.cs215
1 files changed, 215 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs b/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
new file mode 100644
index 00000000..c8153fdb
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
@@ -0,0 +1,215 @@
+using System.Collections.Generic;
+using System.IO;
+
+namespace Ryujinx.HLE.HOS.Ipc
+{
+ class IpcMessage
+ {
+ public IpcMessageType Type { get; set; }
+
+ public IpcHandleDesc HandleDesc { get; set; }
+
+ public List<IpcPtrBuffDesc> PtrBuff { get; private set; }
+ public List<IpcBuffDesc> SendBuff { get; private set; }
+ public List<IpcBuffDesc> ReceiveBuff { get; private set; }
+ public List<IpcBuffDesc> ExchangeBuff { get; private set; }
+ public List<IpcRecvListBuffDesc> RecvListBuff { get; private set; }
+
+ public List<int> ObjectIds { get; private set; }
+
+ public byte[] RawData { get; set; }
+
+ public IpcMessage()
+ {
+ PtrBuff = new List<IpcPtrBuffDesc>();
+ SendBuff = new List<IpcBuffDesc>();
+ ReceiveBuff = new List<IpcBuffDesc>();
+ ExchangeBuff = new List<IpcBuffDesc>();
+ RecvListBuff = new List<IpcRecvListBuffDesc>();
+
+ ObjectIds = new List<int>();
+ }
+
+ public IpcMessage(byte[] Data, long CmdPtr) : this()
+ {
+ using (MemoryStream MS = new MemoryStream(Data))
+ {
+ BinaryReader Reader = new BinaryReader(MS);
+
+ Initialize(Reader, CmdPtr);
+ }
+ }
+
+ private void Initialize(BinaryReader Reader, long CmdPtr)
+ {
+ int Word0 = Reader.ReadInt32();
+ int Word1 = Reader.ReadInt32();
+
+ Type = (IpcMessageType)(Word0 & 0xffff);
+
+ int PtrBuffCount = (Word0 >> 16) & 0xf;
+ int SendBuffCount = (Word0 >> 20) & 0xf;
+ int RecvBuffCount = (Word0 >> 24) & 0xf;
+ int XchgBuffCount = (Word0 >> 28) & 0xf;
+
+ int RawDataSize = (Word1 >> 0) & 0x3ff;
+ int RecvListFlags = (Word1 >> 10) & 0xf;
+ bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0;
+
+ if (HndDescEnable)
+ {
+ HandleDesc = new IpcHandleDesc(Reader);
+ }
+
+ for (int Index = 0; Index < PtrBuffCount; Index++)
+ {
+ PtrBuff.Add(new IpcPtrBuffDesc(Reader));
+ }
+
+ void ReadBuff(List<IpcBuffDesc> Buff, int Count)
+ {
+ for (int Index = 0; Index < Count; Index++)
+ {
+ Buff.Add(new IpcBuffDesc(Reader));
+ }
+ }
+
+ ReadBuff(SendBuff, SendBuffCount);
+ ReadBuff(ReceiveBuff, RecvBuffCount);
+ ReadBuff(ExchangeBuff, XchgBuffCount);
+
+ RawDataSize *= 4;
+
+ long RecvListPos = Reader.BaseStream.Position + RawDataSize;
+
+ long Pad0 = GetPadSize16(Reader.BaseStream.Position + CmdPtr);
+
+ Reader.BaseStream.Seek(Pad0, SeekOrigin.Current);
+
+ int RecvListCount = RecvListFlags - 2;
+
+ if (RecvListCount == 0)
+ {
+ RecvListCount = 1;
+ }
+ else if (RecvListCount < 0)
+ {
+ RecvListCount = 0;
+ }
+
+ RawData = Reader.ReadBytes(RawDataSize);
+
+ Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin);
+
+ for (int Index = 0; Index < RecvListCount; Index++)
+ {
+ RecvListBuff.Add(new IpcRecvListBuffDesc(Reader));
+ }
+ }
+
+ public byte[] GetBytes(long CmdPtr)
+ {
+ using (MemoryStream MS = new MemoryStream())
+ {
+ BinaryWriter Writer = new BinaryWriter(MS);
+
+ int Word0;
+ int Word1;
+
+ Word0 = (int)Type;
+ Word0 |= (PtrBuff.Count & 0xf) << 16;
+ Word0 |= (SendBuff.Count & 0xf) << 20;
+ Word0 |= (ReceiveBuff.Count & 0xf) << 24;
+ Word0 |= (ExchangeBuff.Count & 0xf) << 28;
+
+ byte[] HandleData = new byte[0];
+
+ if (HandleDesc != null)
+ {
+ HandleData = HandleDesc.GetBytes();
+ }
+
+ int DataLength = RawData?.Length ?? 0;
+
+ int Pad0 = (int)GetPadSize16(CmdPtr + 8 + HandleData.Length);
+
+ //Apparently, padding after Raw Data is 16 bytes, however when there is
+ //padding before Raw Data too, we need to subtract the size of this padding.
+ //This is the weirdest padding I've seen so far...
+ int Pad1 = 0x10 - Pad0;
+
+ DataLength = (DataLength + Pad0 + Pad1) / 4;
+
+ Word1 = DataLength & 0x3ff;
+
+ if (HandleDesc != null)
+ {
+ Word1 |= 1 << 31;
+ }
+
+ Writer.Write(Word0);
+ Writer.Write(Word1);
+ Writer.Write(HandleData);
+
+ MS.Seek(Pad0, SeekOrigin.Current);
+
+ if (RawData != null)
+ {
+ Writer.Write(RawData);
+ }
+
+ Writer.Write(new byte[Pad1]);
+
+ return MS.ToArray();
+ }
+ }
+
+ private long GetPadSize16(long Position)
+ {
+ if ((Position & 0xf) != 0)
+ {
+ return 0x10 - (Position & 0xf);
+ }
+
+ return 0;
+ }
+
+ public (long Position, long Size) GetBufferType0x21()
+ {
+ if (PtrBuff.Count != 0 &&
+ PtrBuff[0].Position != 0 &&
+ PtrBuff[0].Size != 0)
+ {
+ return (PtrBuff[0].Position, PtrBuff[0].Size);
+ }
+
+ if (SendBuff.Count != 0 &&
+ SendBuff[0].Position != 0 &&
+ SendBuff[0].Size != 0)
+ {
+ return (SendBuff[0].Position, SendBuff[0].Size);
+ }
+
+ return (0, 0);
+ }
+
+ public (long Position, long Size) GetBufferType0x22()
+ {
+ if (RecvListBuff.Count != 0 &&
+ RecvListBuff[0].Position != 0 &&
+ RecvListBuff[0].Size != 0)
+ {
+ return (RecvListBuff[0].Position, RecvListBuff[0].Size);
+ }
+
+ if (ReceiveBuff.Count != 0 &&
+ ReceiveBuff[0].Position != 0 &&
+ ReceiveBuff[0].Size != 0)
+ {
+ return (ReceiveBuff[0].Position, ReceiveBuff[0].Size);
+ }
+
+ return (0, 0);
+ }
+ }
+}