private void ParseResponseBuffer(byte[] rgbOut, out RPC_HEADER_EXT[] rpcHeaderExts, out byte[][] rops, out uint[][] serverHandleObjectsTables)
{
List<RPC_HEADER_EXT> rpcHeaderExtList = new List<RPC_HEADER_EXT>();
List<byte[]> ropList = new List<byte[]>();
List<uint[]> serverHandleObjectList = new List<uint[]>();
IntPtr ptr = IntPtr.Zero;
int index = 0;
bool end = false;
do
{
// Parse rpc header ext
RPC_HEADER_EXT rpcHeaderExt;
ptr = Marshal.AllocHGlobal(RPCHEADEREXTLEN);
try
{
Marshal.Copy(rgbOut, index, ptr, RPCHEADEREXTLEN);
rpcHeaderExt = (RPC_HEADER_EXT)Marshal.PtrToStructure(ptr, typeof(RPC_HEADER_EXT));
rpcHeaderExtList.Add(rpcHeaderExt);
index += RPCHEADEREXTLEN;
end = (rpcHeaderExt.Flags & (ushort)RpcHeaderExtFlags.Last) == (ushort)RpcHeaderExtFlags.Last;
}
finally
{
Marshal.FreeHGlobal(ptr);
}
#region start parse payload
// Parse ropSize
ushort ropSize = BitConverter.ToUInt16(rgbOut, index);
index += sizeof(ushort);
if ((ropSize - sizeof(ushort)) > 0)
{
// Parse rop
byte[] rop = new byte[ropSize - sizeof(ushort)];
Array.Copy(rgbOut, index, rop, 0, ropSize - sizeof(ushort));
ropList.Add(rop);
index += ropSize - sizeof(ushort);
}
// Parse server handle objects table
this.site.Assert.IsTrue((rpcHeaderExt.Size - ropSize) % sizeof(uint) == 0, "Server object handle should be uint32 array");
int count = (rpcHeaderExt.Size - ropSize) / sizeof(uint);
if (count > 0)
{
uint[] sohs = new uint[count];
for (int k = 0; k < count; k++)
{
sohs[k] = BitConverter.ToUInt32(rgbOut, index);
index += sizeof(uint);
}
serverHandleObjectList.Add(sohs);
}
#endregion
}
while (!end);
rpcHeaderExts = rpcHeaderExtList.ToArray();
rops = ropList.ToArray();
serverHandleObjectsTables = serverHandleObjectList.ToArray();
}