public StackPacket DecodeTsFpInputPDU(RdpbcgrServerSessionContext serverSessionContext, byte[] data)
{
int currentIndex = 0;
TS_FP_INPUT_PDU pdu = new TS_FP_INPUT_PDU();
pdu.fpInputHeader.actionCode = ParseByte(data, ref currentIndex);
nested_TS_FP_UPDATE_PDU_fpOutputHeader_actionCode_Values actionCode;
byte numberEvents;
encryptionFlagsChgd_Values encryptionFlags;
GetFpInputHeaderInfo(pdu.fpInputHeader.actionCode, out actionCode, out numberEvents, out encryptionFlags);
pdu.length1 = ParseByte(data, ref currentIndex);
if ((ConstValue.MOST_SIGNIFICANT_BIT_FILTER & pdu.length1) != pdu.length1)
{
// length2 is present (since the most significant bit of length1 is set)
pdu.length2 = ParseByte(data, ref currentIndex);
}
// TS_FP_UPDATE_PDU: fipsInformation
if (EncryptionLevel.ENCRYPTION_LEVEL_FIPS == serverSessionContext.RdpEncryptionLevel)
{
pdu.fipsInformation = ParseTsFpFipsInfo(data, ref currentIndex);
}
// TS_FP_UPDATE_PDU: dataSignature
if (IsFlagExist((byte)encryptionFlags, (byte)encryptionFlagsChgd_Values.FASTPATH_OUTPUT_ENCRYPTED))
{
// pdu were encrypted, data signature exists
pdu.dataSignature = GetBytes(data, ref currentIndex,
ConstValue.TS_FP_UPDATE_PDU_DATA_SIGNATURE_LENGTH);
}
else
{
pdu.dataSignature = null;
}
// Decryption
bool isSalted = IsFlagExist((byte)encryptionFlags,
(byte)encryptionFlagsChgd_Values.FASTPATH_OUTPUT_SECURE_CHECKSUM);
byte[] remainData = GetBytes(data, ref currentIndex, (data.Length - currentIndex));
byte[] decryptedData = DecryptFastPathInputData(serverSessionContext, remainData, pdu.dataSignature, isSalted);
// Decrypted data index
int decryptedDataIndex = 0;
//[yunzed]
if( numberEvents == 0 )
{
Console.WriteLine("numberEvents is 0, so parse the additional numberEvents");
pdu.numberEvents = ParseByte(decryptedData, ref decryptedDataIndex);
}
// TS_FP_UPDATE_PDU: fpOutputUpdates
pdu.fpInputEvents= ParseTsFpInputEvents(decryptedData, ref decryptedDataIndex);
// ETW Provider Dump Message
if (pdu.dataSignature != null)
{
// Fast-Path encrypted
string messageName = "RDPBCGR:" + pdu.GetType().Name;
ExtendedLogger.DumpMessage(messageName, RdpbcgrUtility.DumpLevel_Layer3, pdu.GetType().Name, decryptedData);
}
// Check if data length exceeded expectation
VerifyDataLength(decryptedData.Length, decryptedDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED);
return pdu;
}