private byte[] BuildRequestBuffer(List<ISerializable> requestROPs, List<uint> requestSOHTable)
{
// Definition for PayloadLen which indicates the length of the field that represents the length of payload.
int payloadLen = 0x2;
if (requestROPs != null)
{
foreach (ISerializable requestROP in requestROPs)
{
payloadLen += requestROP.Size();
}
}
ushort ropSize = (ushort)payloadLen;
if (requestSOHTable != null)
{
payloadLen += requestSOHTable.Count * sizeof(uint);
}
byte[] requestBuffer = new byte[RPCHEADEREXTLEN + payloadLen];
int index = 0;
// Construct RPC header ext buffer
RPC_HEADER_EXT rpcHeaderExt = new RPC_HEADER_EXT
{
// There is only one version of the header at this time so this value MUST be set to 0x00.
Version = 0x00,
// Last (0x04) indicates that no other RPC_HEADER_EXT follows the data of the current RPC_HEADER_EXT.
Flags = (ushort)RpcHeaderExtFlags.Last,
Size = (ushort)payloadLen
};
rpcHeaderExt.SizeActual = rpcHeaderExt.Size;
IntPtr ptr = Marshal.AllocHGlobal(RPCHEADEREXTLEN);
try
{
Marshal.StructureToPtr(rpcHeaderExt, ptr, true);
Marshal.Copy(ptr, requestBuffer, index, RPCHEADEREXTLEN);
index += RPCHEADEREXTLEN;
}
finally
{
Marshal.FreeHGlobal(ptr);
}
// RopSize's type is ushort. So the offset will be 2.
Array.Copy(BitConverter.GetBytes(ropSize), 0, requestBuffer, index, 2);
index += 2;
if (requestROPs != null)
{
foreach (ISerializable requestROP in requestROPs)
{
Array.Copy(requestROP.Serialize(), 0, requestBuffer, index, requestROP.Size());
index += requestROP.Size();
}
}
if (requestSOHTable != null)
{
foreach (uint serverHandle in requestSOHTable)
{
Array.Copy(BitConverter.GetBytes(serverHandle), 0, requestBuffer, index, sizeof(uint));
index += sizeof(uint);
}
}
// Compress and obfuscate request buffer as configured.
requestBuffer = Common.CompressAndObfuscateRequest(requestBuffer, this.site);
return requestBuffer;
}