/// <summary> /// Decode Virtual Channel PDU /// </summary> /// <param name="data">data to be parsed</param> /// <param name="decryptedUserData">decrypted user data</param> /// <param name="type">security header type</param> /// <returns>decoded Virtual Channel PDU</returns> public StackPacket DecodeVirtualChannelPDU( byte[] data, byte[] decryptedUserData, SecurityHeaderType type) { Virtual_Channel_RAW_Server_Pdu pdu = new Virtual_Channel_RAW_Server_Pdu(); // data index int dataIndex = 0; // Virtual_Channel_RAW_Pdu: commonHeader pdu.commonHeader = ParseMcsCommonHeader(data, ref dataIndex, type); // user data index int userDataIndex = 0; // Virtual_Channel_RAW_PDU: channelPduHeader pdu.channelPduHeader = ParseChannelPduHeader(decryptedUserData, ref userDataIndex); // Virtual_Channel_RAW_PDU: virtualChannelData int remainLength = decryptedUserData.Length - Marshal.SizeOf(pdu.channelPduHeader); pdu.virtualChannelData = GetBytes(decryptedUserData, ref userDataIndex, remainLength); // Check if data length exceeded expectation VerifyDataLength(decryptedUserData.Length, userDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// Reassemble chunk data by the member field channelManager. /// This method is called when processing Virtual Channel PDU. /// </summary> /// <param name="pdu">The channel pdu includes header and data. This argument can be null.</param> /// <returns>If the reassemble is complete, then return the Virtual_Channel_Complete_PDU. /// Else return null.</returns> public Virtual_Channel_Complete_Server_Pdu ReassembleChunkData(Virtual_Channel_RAW_Server_Pdu pdu) { lock (contextLock) { return channelManager.ReassembleChunkData(pdu); } }
/// <summary> /// Send static virtual channel data /// </summary> /// <param name="channelId">Channel ID</param> /// <param name="channelPduHeader">Channel PDU Header</param> /// <param name="SVCData"></param> public void SendPacket(UInt16 channelId, CHANNEL_PDU_HEADER channelPduHeader, byte[] SVCData) { Virtual_Channel_RAW_Server_Pdu rawPdu = new Virtual_Channel_RAW_Server_Pdu(context); rawPdu.channelPduHeader = channelPduHeader; rawPdu.virtualChannelData = SVCData; RdpbcgrUtility.FillCommonHeader(ref rawPdu.commonHeader, TS_SECURITY_HEADER_flags_Values.SEC_IGNORE_SEQNO | TS_SECURITY_HEADER_flags_Values.SEC_RESET_SEQNO, context, channelId); context.Server.SendPdu(context, rawPdu); }
public override StackPacket Clone() { Virtual_Channel_RAW_Server_Pdu pduClone = new Virtual_Channel_RAW_Server_Pdu(); pduClone.commonHeader = commonHeader; pduClone.channelPduHeader = channelPduHeader; pduClone.virtualChannelData = RdpbcgrUtility.CloneByteArray(virtualChannelData); return pduClone; }
/// <summary> /// Split the virtualChannelData to several chunk data to send. /// </summary> public void SplitToChunks() { ChannelChunk[] chunks = serverSessionContext.SplitToChunks(channelId, virtualChannelData); if (chunks != null && chunks.Length > 0) { rawPdus = new Collection<Virtual_Channel_RAW_Server_Pdu>(); for (int i = 0; i < chunks.Length; ++i) { Virtual_Channel_RAW_Server_Pdu rawPdu = new Virtual_Channel_RAW_Server_Pdu(serverSessionContext); rawPdu.channelPduHeader = chunks[i].channelPduHeader; rawPdu.virtualChannelData = chunks[i].chunkData; rawPdus.Add(rawPdu); RdpbcgrUtility.FillCommonHeader(ref rawPdus[i].commonHeader, TS_SECURITY_HEADER_flags_Values.SEC_IGNORE_SEQNO | TS_SECURITY_HEADER_flags_Values.SEC_RESET_SEQNO, serverSessionContext, channelId); } } }
public Virtual_Channel_RAW_Server_Pdu_Ex(Virtual_Channel_RAW_Server_Pdu orgPdu, RdpbcgrServerSessionContext serverSessionContext) : base(serverSessionContext) { this.commonHeader = orgPdu.commonHeader; this.channelPduHeader = orgPdu.channelPduHeader; this.virtualChannelData = orgPdu.virtualChannelData; }
/// <summary> /// Reassemble static virtual channel PDU /// </summary> /// <param name="pdu"></param> /// <returns></returns> internal Virtual_Channel_Complete_Server_Pdu ReassembleChunkData(Virtual_Channel_RAW_Server_Pdu pdu) { if (pdu == null || pdu.virtualChannelData == null) { return null; } // the first chunk if ((pdu.channelPduHeader.flags & CHANNEL_PDU_HEADER_flags_Values.CHANNEL_FLAG_FIRST) == CHANNEL_PDU_HEADER_flags_Values.CHANNEL_FLAG_FIRST) { completeServerPdu = new Virtual_Channel_Complete_Server_Pdu(); completeServerPdu.rawPdus = new System.Collections.ObjectModel.Collection<Virtual_Channel_RAW_Server_Pdu>(); completeServerPdu.channelId = channelId; decompressedBuffer.Clear(); } byte[] decompressedData = pdu.virtualChannelData; if (mppcDecompressor != null) // has compression { CompressMode flag = CompressMode.None; if ((pdu.channelPduHeader.flags & CHANNEL_PDU_HEADER_flags_Values.CHANNEL_PACKET_AT_FRONT) == CHANNEL_PDU_HEADER_flags_Values.CHANNEL_PACKET_AT_FRONT) { flag |= CompressMode.SetToFront; } if ((pdu.channelPduHeader.flags & CHANNEL_PDU_HEADER_flags_Values.CHANNEL_PACKET_COMPRESSED) == CHANNEL_PDU_HEADER_flags_Values.CHANNEL_PACKET_COMPRESSED) { flag |= CompressMode.Compressed; } if ((pdu.channelPduHeader.flags & CHANNEL_PDU_HEADER_flags_Values.CHANNEL_PACKET_FLUSHED) == CHANNEL_PDU_HEADER_flags_Values.CHANNEL_PACKET_FLUSHED) { flag |= CompressMode.Flush; } if (flag != CompressMode.None) { decompressedData = mppcDecompressor.Decompress(pdu.virtualChannelData, flag); } } if (completeServerPdu != null) { completeServerPdu.rawPdus.Add(pdu); decompressedBuffer.AddRange(decompressedData); } else { // not need to reassemble Virtual_Channel_Complete_Server_Pdu returnPDU = new Virtual_Channel_Complete_Server_Pdu(); returnPDU.rawPdus = new System.Collections.ObjectModel.Collection<Virtual_Channel_RAW_Server_Pdu>(); returnPDU.channelId = channelId; returnPDU.rawPdus.Add(pdu); returnPDU.virtualChannelData = decompressedData; return returnPDU; } // the last chunk if ((pdu.channelPduHeader.flags & CHANNEL_PDU_HEADER_flags_Values.CHANNEL_FLAG_LAST) == CHANNEL_PDU_HEADER_flags_Values.CHANNEL_FLAG_LAST) { if (decompressedBuffer != null) { completeServerPdu.virtualChannelData = decompressedBuffer.ToArray(); } Virtual_Channel_Complete_Server_Pdu returnPDU = completeServerPdu; completeServerPdu = null; return returnPDU; } return null; }