mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 19:42:58 +00:00
551 lines
17 KiB
C#
551 lines
17 KiB
C#
using Esiur.Data;
|
|
using Esiur.Engine;
|
|
using Esiur.Misc;
|
|
using Esiur.Net.Packets;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Esiur.Net.Packets
|
|
{
|
|
class IIPPacket : Packet
|
|
{
|
|
public enum IIPPacketCommand : byte
|
|
{
|
|
Event = 0,
|
|
Request,
|
|
Reply,
|
|
Error,
|
|
}
|
|
|
|
public enum IIPPacketEvent: byte
|
|
{
|
|
// Event Manage
|
|
ResourceReassigned = 0,
|
|
ResourceDestroyed,
|
|
|
|
// Event Invoke
|
|
PropertyUpdated = 0x10,
|
|
EventOccured,
|
|
}
|
|
|
|
public enum IIPPacketAction : byte
|
|
{
|
|
// Request Manage
|
|
AttachResource = 0,
|
|
ReattachResource,
|
|
DetachResource,
|
|
CreateResource,
|
|
DeleteResource,
|
|
|
|
// Request Inquire
|
|
TemplateFromClassName = 0x8,
|
|
TemplateFromClassId,
|
|
TemplateFromResourceLink,
|
|
TemplateFromResourceId,
|
|
ResourceIdFromResourceLink,
|
|
|
|
// Request Invoke
|
|
InvokeFunction = 0x10,
|
|
GetProperty,
|
|
GetPropertyIfModified,
|
|
SetProperty,
|
|
}
|
|
|
|
|
|
public IIPPacketCommand Command
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
public IIPPacketAction Action
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public IIPPacketEvent Event
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
|
|
public uint ResourceId { get; set; }
|
|
public uint NewResourceId { get; set; }
|
|
|
|
public uint ResourceAge { get; set; }
|
|
public byte[] Content { get; set; }
|
|
public byte ErrorCode { get; set; }
|
|
public string ErrorMessage { get; set; }
|
|
public string ClassName { get; set; }
|
|
public string ResourceLink { get; set; }
|
|
public Guid ClassId { get; set; }
|
|
public byte MethodIndex { get; set; }
|
|
public string MethodName { get; set; }
|
|
public uint CallbackId { get; set; }
|
|
|
|
private uint dataLengthNeeded;
|
|
|
|
public override bool Compose()
|
|
{
|
|
return base.Compose();
|
|
}
|
|
|
|
bool NotEnough(uint offset, uint ends, uint needed)
|
|
{
|
|
if (offset + needed > ends)
|
|
{
|
|
dataLengthNeeded = needed - (ends - offset);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
public override long Parse(byte[] data, uint offset, uint ends)
|
|
{
|
|
var oOffset = offset;
|
|
|
|
if (NotEnough(offset, ends, 1))
|
|
return -dataLengthNeeded;
|
|
|
|
Command = (IIPPacketCommand)(data[offset] >> 6);
|
|
|
|
if (Command == IIPPacketCommand.Event)
|
|
{
|
|
Event = (IIPPacketEvent)(data[offset++] & 0x3f);
|
|
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
}
|
|
else
|
|
{
|
|
Action = (IIPPacketAction)(data[offset++] & 0x3f);
|
|
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
CallbackId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
}
|
|
|
|
if (Command == IIPPacketCommand.Event)
|
|
{
|
|
if (Event == IIPPacketEvent.ResourceReassigned)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
NewResourceId = data.GetUInt32( offset);
|
|
offset += 4;
|
|
|
|
}
|
|
else if (Event == IIPPacketEvent.ResourceDestroyed)
|
|
{
|
|
// nothing to parse
|
|
}
|
|
else if (Event == IIPPacketEvent.PropertyUpdated)
|
|
{
|
|
if (NotEnough(offset, ends, 2))
|
|
return -dataLengthNeeded;
|
|
|
|
MethodIndex = data[offset++];
|
|
|
|
var dt = (DataType)data[offset++];
|
|
var size = dt.Size();// Codec.SizeOf(dt);
|
|
|
|
if (size < 0)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt32( offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip( offset - 5, cl + 5);
|
|
offset += cl;
|
|
}
|
|
else
|
|
{
|
|
if (NotEnough(offset, ends, (uint)size))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
offset += (uint)size;
|
|
}
|
|
}
|
|
else if (Event == IIPPacketEvent.EventOccured)
|
|
{
|
|
if (NotEnough(offset, ends, 5))
|
|
return -dataLengthNeeded;
|
|
|
|
MethodIndex = data[offset++];
|
|
|
|
var cl = data.GetUInt32( offset);
|
|
offset += 4;
|
|
|
|
Content = data.Clip( offset, cl);
|
|
offset += cl;
|
|
|
|
}
|
|
}
|
|
else if (Command == IIPPacketCommand.Request)
|
|
{
|
|
if (Action == IIPPacketAction.AttachResource)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
}
|
|
else if (Action == IIPPacketAction.ReattachResource)
|
|
{
|
|
if (NotEnough(offset, ends, 8))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
ResourceAge = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.DetachResource)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.CreateResource)
|
|
{
|
|
if (NotEnough(offset, ends, 1))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data[offset++];
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
ClassName = data.GetString(offset, cl);
|
|
offset += cl;
|
|
}
|
|
else if (Action == IIPPacketAction.DeleteResource)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.TemplateFromClassName)
|
|
{
|
|
if (NotEnough(offset, ends, 1))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data[offset++];
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
ClassName = data.GetString(offset, cl);
|
|
offset += cl;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.TemplateFromClassId)
|
|
{
|
|
if (NotEnough(offset, ends, 16))
|
|
return -dataLengthNeeded;
|
|
|
|
ClassId = data.GetGuid(offset);
|
|
offset += 16;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.TemplateFromResourceLink)
|
|
{
|
|
if (NotEnough(offset, ends, 2))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt16(offset);
|
|
offset += 2;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceLink = data.GetString(offset, cl);
|
|
offset += cl;
|
|
}
|
|
else if (Action == IIPPacketAction.TemplateFromResourceId)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
}
|
|
else if (Action == IIPPacketAction.ResourceIdFromResourceLink)
|
|
{
|
|
if (NotEnough(offset, ends, 2))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt16(offset);
|
|
offset += 2;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceLink = data.GetString(offset, cl);
|
|
offset += cl;
|
|
}
|
|
else if (Action == IIPPacketAction.InvokeFunction)
|
|
{
|
|
if (NotEnough(offset, ends, 9))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
MethodIndex = data[offset++];
|
|
|
|
var cl = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset, cl);
|
|
offset += cl;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.GetProperty)
|
|
{
|
|
if (NotEnough(offset, ends, 5))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
MethodIndex = data[offset++];
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.GetPropertyIfModified)
|
|
{
|
|
if (NotEnough(offset, ends, 9))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
MethodIndex = data[offset++];
|
|
|
|
ResourceAge = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.SetProperty)
|
|
{
|
|
if (NotEnough(offset, ends, 6))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
MethodIndex = data[offset++];
|
|
|
|
|
|
var dt = (DataType)data[offset++];
|
|
var size = dt.Size();// Codec.SizeOf(dt);
|
|
|
|
if (size < 0)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset-5, cl + 5);
|
|
offset += cl;
|
|
}
|
|
else
|
|
{
|
|
if (NotEnough(offset, ends, (uint)size))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset-1, (uint)size + 1);
|
|
offset += (uint)size;
|
|
}
|
|
}
|
|
}
|
|
else if (Command == IIPPacketCommand.Reply)
|
|
{
|
|
if (Action == IIPPacketAction.AttachResource
|
|
|| Action == IIPPacketAction.ReattachResource)
|
|
{
|
|
|
|
if (NotEnough(offset, ends, 26))
|
|
return -dataLengthNeeded;
|
|
|
|
ClassId = data.GetGuid(offset);
|
|
offset += 16;
|
|
|
|
ResourceAge = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
uint cl = data.GetUInt16(offset);
|
|
offset += 2;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
ResourceLink = data.GetString(offset, cl);
|
|
offset += cl;
|
|
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
cl = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset, cl);
|
|
offset += cl;
|
|
}
|
|
else if (Action == IIPPacketAction.DetachResource)
|
|
{
|
|
// nothing to do
|
|
}
|
|
else if (Action == IIPPacketAction.CreateResource)
|
|
{
|
|
if (NotEnough(offset, ends, 20))
|
|
return -dataLengthNeeded;
|
|
|
|
ClassId = data.GetGuid(offset);
|
|
offset += 16;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
}
|
|
else if (Action == IIPPacketAction.DetachResource)
|
|
{
|
|
// nothing to do
|
|
}
|
|
else if (Action == IIPPacketAction.TemplateFromClassName
|
|
|| Action == IIPPacketAction.TemplateFromClassId
|
|
|| Action == IIPPacketAction.TemplateFromResourceLink
|
|
|| Action == IIPPacketAction.TemplateFromResourceId)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset, cl);
|
|
offset += cl;
|
|
}
|
|
else if (Action == IIPPacketAction.ResourceIdFromResourceLink)
|
|
{
|
|
if (NotEnough(offset, ends, 24))
|
|
return -dataLengthNeeded;
|
|
|
|
ClassId = data.GetGuid(offset);
|
|
offset += 16;
|
|
|
|
ResourceId = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
ResourceAge = data.GetUInt32(offset);
|
|
offset += 4;
|
|
}
|
|
else if (Action == IIPPacketAction.InvokeFunction
|
|
|| Action == IIPPacketAction.GetProperty
|
|
|| Action == IIPPacketAction.GetPropertyIfModified)
|
|
{
|
|
if (NotEnough(offset, ends, 1))
|
|
return -dataLengthNeeded;
|
|
|
|
var dt = (DataType)data[offset++];
|
|
var size = dt.Size();// Codec.SizeOf(dt);
|
|
|
|
if (size < 0)
|
|
{
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset - 5, cl + 5);
|
|
offset += cl;
|
|
}
|
|
else
|
|
{
|
|
if (NotEnough(offset, ends, (uint)size))
|
|
return -dataLengthNeeded;
|
|
|
|
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
offset += (uint)size;
|
|
}
|
|
}
|
|
else if (Action == IIPPacketAction.SetProperty)
|
|
{
|
|
// nothing to do
|
|
}
|
|
}
|
|
else if (Command == IIPPacketCommand.Error)
|
|
{
|
|
// Error
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
CallbackId = data.GetUInt32(offset);
|
|
|
|
if (NotEnough(offset, ends, 1))
|
|
return -dataLengthNeeded;
|
|
|
|
ErrorCode = data[offset++];
|
|
|
|
if (NotEnough(offset, ends, 4))
|
|
return -dataLengthNeeded;
|
|
|
|
var cl = data.GetUInt32(offset);
|
|
offset += 4;
|
|
|
|
if (NotEnough(offset, ends, cl))
|
|
return -dataLengthNeeded;
|
|
|
|
ErrorMessage = data.GetString(offset, cl);
|
|
offset += cl;
|
|
}
|
|
|
|
return offset - oOffset;
|
|
}
|
|
}
|
|
}
|