/// <summary> /// Expect a DVC Capabilities Request PDU /// </summary> /// <param name="timeout">Timeout</param> /// <param name="transportType">Transport type</param> /// <returns></returns> private DynamicVCPDU ExpectDVCCapRequestPDU(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { if (unprocessedDVCPacketBuffer.Count > 0) { lock (unprocessedDVCPacketBuffer) { for (int i = 0; i < unprocessedDVCPacketBuffer.Count; i++) { if (transportType == unprocessedDVCPacketBuffer[i].TransportType && (unprocessedDVCPacketBuffer[i].PDU is CapsVer1ReqDvcPdu || unprocessedDVCPacketBuffer[i].PDU is CapsVer2ReqDvcPdu || unprocessedDVCPacketBuffer[i].PDU is CapsVer3ReqDvcPdu)) { DynamicVCPDU capResp = unprocessedDVCPacketBuffer[i].PDU; unprocessedDVCPacketBuffer.RemoveAt(i); return(capResp); } } } } Thread.Sleep(this.waitInterval); } return(null); }
/// <summary> /// Process DVC packet, but don't process data packet /// Data packet will be processed by corresponding Dynamic virtual channel /// </summary> /// <param name="pdu">DVC packet</param> /// <param name="transportType">Transport type</param> private void ProcessPacket(DynamicVCPDU pdu, DynamicVC_TransportType transportType) { if (pdu is DataDvcBasePdu) { DataDvcBasePdu dataPdu = pdu as DataDvcBasePdu; if (channelDicbyId.ContainsKey(dataPdu.ChannelId)) { channelDicbyId[dataPdu.ChannelId].ProcessPacket(dataPdu); } } else { if (autoCreateChannel) { if (pdu is CreateReqDvcPdu) { this.EstablishChannel(pdu as CreateReqDvcPdu, transportType); return; } else if (pdu is CloseDvcPdu) { this.CloseChannel(pdu as CloseDvcPdu); return; } } lock (unprocessedDVCPacketBuffer) { unprocessedDVCPacketBuffer.Add(new UnprocessedDVCPDUInfo(pdu, transportType)); } } }
public DynamicVCPDU ToPdu(byte[] data) { if (null == regsiteredPDUs) { regsiteredPDUs = new List <DynamicVCPDU>(); RegisterDefaultPdus(); } DynamicVCPDU res = null; foreach (DynamicVCPDU pdu in regsiteredPDUs) { if (PduMarshaler.Unmarshal(data, pdu)) { res = pdu; break; } } if (res == null) { DynamicVCException.Throw("UnknownDynamicVCPDU was not registered."); } // Clear references in the list and register new PDUs. regsiteredPDUs.Clear(); RegisterDefaultPdus(); return(res); }
/// <summary> /// Exchange DYNVC_DATA response from RDP server /// </summary> /// <param name="version"></param> public DynamicVCPDU ExpectDynvcData(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { if (unprocessedDVCPacketBuffer.Count > 0) { lock (unprocessedDVCPacketBuffer) { for (int i = 0; i < unprocessedDVCPacketBuffer.Count; i++) { if (transportType == unprocessedDVCPacketBuffer[i].TransportType && unprocessedDVCPacketBuffer[i].PDU is DynamicVCPDU) { DynamicVCPDU rep = unprocessedDVCPacketBuffer[i].PDU as DynamicVCPDU; if (rep.HeaderBits.Cmd == Cmd_Values.Data) { unprocessedDVCPacketBuffer.RemoveAt(i); return(rep); } } } } } Thread.Sleep(this.waitInterval); } return(null); }
/// <summary> /// Send a PDU using a specific transport /// </summary> /// <param name="pdu"></param> /// <param name="transportType"></param> public void Send(DynamicVCPDU pdu, DynamicVC_TransportType transportType) { if (!transportDic.ContainsKey(transportType)) { throw new InvalidOperationException("Not create DVC transport:" + transportType); } transportDic[transportType].Send(pdu); }
/// <summary> /// Send a PDU using a specific transport /// </summary> /// <param name="pdu"></param> /// <param name="transportType"></param> private void Send(DynamicVCPDU pdu, DynamicVC_TransportType transportType) { if (!transportDic.ContainsKey(transportType)) { throw new InvalidOperationException(string.Format("The DVC transport {0} is not created.", transportType)); } transportDic[transportType].Send(pdu); }
private void SendFirstCompressedDataPdu(uint channelId, byte[] data, DynamicVC_TransportType transport, uint?dataLength = null) { //According to section 3.1.5.1.4 of MS-RDPEDYC, //If the total uncompressed length of the message exceeds 1,590 bytes, //the DYNVC_DATA_FIRST_COMPRESSED (section 2.2.3.3) PDU is sent as the first data PDU, //followed by DYNVC_DATA_COMPRESSED (section 2.2.3.4) PDUs until all the data has been sent. if (data.Length <= ConstLength.MAX_UNCOMPRESSED_DATA_LENGTH) { byte[] compressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(data, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DataFirstCompressedDvcPdu firstCompressedPdu = new DataFirstCompressedDvcPdu(channelId, (uint)data.Length, compressedData); firstCompressedPdu.GetNonDataSize(); Send(firstCompressedPdu, transport); } else { //Cmd:4 bits, Len: 2 bits, cbChid:2 bits, ChannelId: 8 bit, Length: no more than 1600, so it it 16 bits. Totally, 4 bytes // Descriptor is 1 byte, Header is 1 byte //So the max length of the data should be 1600 (Max Chunk Length)-6 byte[] uncompressedData = new byte[ConstLength.MAX_FIRST_COMPRESSED_DATA_LENGTH]; Array.Copy(data, uncompressedData, ConstLength.MAX_FIRST_COMPRESSED_DATA_LENGTH); byte[] compressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(uncompressedData, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DataFirstCompressedDvcPdu firstCompressedPdu = new DataFirstCompressedDvcPdu(channelId, (uint)data.Length, compressedData); firstCompressedPdu.GetNonDataSize(); Send(firstCompressedPdu, transport); int leftBytes = uncompressedData.Length - (int)ConstLength.MAX_FIRST_COMPRESSED_DATA_LENGTH; int followingMsgCount = 0; if (leftBytes > 0) { int followingLen = data.Length - (int)ConstLength.MAX_FIRST_COMPRESSED_DATA_LENGTH; followingMsgCount = (followingLen / (int)ConstLength.MAX_COMPRESSED_DATA_LENGTH); followingMsgCount = (followingLen % (int)ConstLength.MAX_COMPRESSED_DATA_LENGTH == 0) ? followingMsgCount : ++followingMsgCount; for (int i = 0; i < followingMsgCount; i++) { if (i != followingMsgCount) { byte[] followingUnCompressedData = new byte[ConstLength.MAX_COMPRESSED_DATA_LENGTH]; Array.Copy(data, i * ConstLength.MAX_COMPRESSED_DATA_LENGTH + ConstLength.MAX_FIRST_COMPRESSED_DATA_LENGTH, followingUnCompressedData, 0, ConstLength.MAX_COMPRESSED_DATA_LENGTH); byte[] followingCompressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(followingUnCompressedData, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DynamicVCPDU followingCompressedPDU = pduBuilder.CreateDataCompressedReqPdu(channelId, followingCompressedData); Send(followingCompressedPDU, transport); } else //Last message { byte[] lastUnCompressedData = new byte[data.Length - i * ConstLength.MAX_COMPRESSED_DATA_LENGTH]; Array.Copy(data, i * ConstLength.MAX_COMPRESSED_DATA_LENGTH + ConstLength.MAX_FIRST_COMPRESSED_DATA_LENGTH, lastUnCompressedData, 0, followingLen - i * ConstLength.MAX_COMPRESSED_DATA_LENGTH); byte[] lastCompressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(lastUnCompressedData, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DynamicVCPDU followingPdu = pduBuilder.CreateDataCompressedReqPdu(channelId, lastCompressedData); Send(followingPdu, transport); } } } } }
public void RegisterPdu(DynamicVCPDU pdu) { if (null == regsiteredPDUs) { regsiteredPDUs = new List <DynamicVCPDU>(); } regsiteredPDUs.Add(pdu); }
/// <summary> /// Process bytes received /// </summary> /// <param name="data"></param> private void ReceivedBytes(byte[] data) { DynamicVCPDU pdu = decoder.ToPdu(data); if (Received != null) { Received(pdu); } }
public void SendFirstCompressedDataPdu(uint channelId, byte[] data) { if (data.Length < 1599 - 4)//Cmd:4 bits, Len: 2 bits, cbChid:2 bits, ChannelId: 8 bit, Length: no more than 1599, so it it 16 bits. Totally, 4 bytes { byte[] compressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(data, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DataFirstCompressedDvcPdu firstCompressedPdu = new DataFirstCompressedDvcPdu(channelId, (uint)data.Length, compressedData); firstCompressedPdu.GetNonDataSize(); Send(firstCompressedPdu, DynamicVC_TransportType.RDP_UDP_Reliable); } else { //Cmd:4 bits, Len: 2 bits, cbChid:2 bits, ChannelId: 8 bit, Length: no more than 1599, so it it 16 bits. Totally, 4 bytes //So the max length of the data should be 1599-4 byte[] uncompressedData = new byte[1595]; Array.Copy(data, uncompressedData, 1599 - 4); byte[] compressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(uncompressedData, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DataFirstCompressedDvcPdu firstCompressedPdu = new DataFirstCompressedDvcPdu(channelId, (uint)data.Length, compressedData); firstCompressedPdu.GetNonDataSize(); Send(firstCompressedPdu, DynamicVC_TransportType.RDP_UDP_Reliable); int leftBytes = uncompressedData.Length % 1595; int followingMsgCount = 0; if (leftBytes > 0) { followingMsgCount = data.Length / 1595 + 1 - 1; //minus the FirstCompressedData for (int i = 0; i < followingMsgCount; i++) { if (i != followingMsgCount) { byte[] followingUnCompressedData = new byte[1595]; Array.Copy(data, i * 1595, followingUnCompressedData, 0, 1595); byte[] followingCompressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(followingUnCompressedData, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DynamicVCPDU followingCompressedPDU = pduBuilder.CreateDataCompressedReqPdu(channelId, followingCompressedData); Send(followingCompressedPDU, DynamicVC_TransportType.RDP_UDP_Reliable); } else //Last message { byte[] lastUnCompressedData = new byte[data.Length - i * 1595]; Array.Copy(data, i * 1595, lastUnCompressedData, 0, data.Length - i * 1595); byte[] lastCompressedData = pduBuilder.CompressDataToRdp8BulkEncodedData(lastUnCompressedData, PACKET_COMPR_FLAG.PACKET_COMPR_TYPE_LITE | PACKET_COMPR_FLAG.PACKET_COMPRESSED); DynamicVCPDU followingPdu = pduBuilder.CreateDataCompressedReqPdu(channelId, lastCompressedData); Send(followingPdu, DynamicVC_TransportType.RDP_UDP_Reliable); } } } } }
/// <summary> /// Process bytes received /// </summary> /// <param name="data"></param> private void ReceivedBytes(byte[] data) { if (Received == null) { cachedData.Enqueue(data); } else { while (cachedData.TryDequeue(out var res)) { DynamicVCPDU cachedPdu = decoder.ToPdu(res); Received(cachedPdu); } DynamicVCPDU pdu = decoder.ToPdu(data); Received(pdu); } }
/// <summary> /// Send DVC Capabilities Request PDU /// </summary> /// <param name="version">Version of Cap Request</param> /// <param name="transportType">transport Type</param> private void SendDVCCapRequestPDU(DYNVC_CAPS_Version version, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { DynamicVCPDU capReq = null; if (version == DYNVC_CAPS_Version.VERSION1) { capReq = pduBuilder.CreateCapsV1ReqPdu(); } else if (version == DYNVC_CAPS_Version.VERSION2) { capReq = pduBuilder.CreateCapsV2ReqPdu(); } else { capReq = pduBuilder.CreateCapsV3ReqPdu(); } this.Send(capReq, transportType); }
/// <summary> /// Exchange DVC capability, negotiate the version /// </summary> /// <param name="version"></param> public void ExchangeCapabilities(TimeSpan timeout) { DynamicVCPDU pdu = this.ExpectDVCCapRequestPDU(timeout); if (pdu == null) { throw new System.IO.IOException("Cannot receive a DVC Capabilities Request PDU!"); } DYNVC_CAPS_Version version = DYNVC_CAPS_Version.VERSION3; if (pdu is CapsVer1ReqDvcPdu) { version = DYNVC_CAPS_Version.VERSION1; } else if (pdu is CapsVer2ReqDvcPdu) { version = DYNVC_CAPS_Version.VERSION2; } this.SendDVCCapResponsePDU(version); }
public byte[] ToRawData(DynamicVCPDU pdu) { return PduMarshaler.Marshal(pdu); }
public void RegisterPdu(DynamicVCPDU pdu) { if (null == regsiteredPDUs) { regsiteredPDUs = new List<DynamicVCPDU>(); } regsiteredPDUs.Add(pdu); }
public byte[] ToRawData(DynamicVCPDU pdu) { return(PduMarshaler.Marshal(pdu)); }
/// <summary> /// Send a Dynamic virtual channel PDU /// </summary> /// <param name="pdu"></param> public void Send(DynamicVCPDU pdu) { rdpemtServer.Send(pduBuilder.ToRawData(pdu)); }
public UnprocessedDVCPDUInfo(DynamicVCPDU pdu, DynamicVC_TransportType type) { this.PDU = pdu; this.TransportType = type; }
/// <summary> /// Process Packet from reliable UDP transport /// </summary> /// <param name="pdu"></param> private void ProcessPacketFromUDPR(DynamicVCPDU pdu) { ProcessPacket(pdu, DynamicVC_TransportType.RDP_UDP_Reliable); }
public UnprocessedDVCPDUInfo(DynamicVCPDU pdu, DynamicVC_TransportType type) { this.PDU = pdu; this.TransportType = type; }
/// <summary> /// Send a PDU using a specific transport /// </summary> /// <param name="pdu"></param> /// <param name="transportType"></param> public void Send(DynamicVCPDU pdu, DynamicVC_TransportType transportType) { if (!transportDic.ContainsKey(transportType)) { throw new InvalidOperationException("Not create DVC transport:" + transportType); } transportDic[transportType].Send(pdu); }
/// <summary> /// Send a Dynamic virtual channel PDU /// </summary> /// <param name="pdu"></param> public void Send(DynamicVCPDU pdu) { channel.Send(pduBuilder.ToRawData(pdu)); }
/// <summary> /// Process DVC packet, but don't process data packet /// Data packet will be processed by corresponding Dynamic virtual channel /// </summary> /// <param name="pdu">DVC packet</param> /// <param name="transportType">Transport type</param> private void ProcessPacket(DynamicVCPDU pdu, DynamicVC_TransportType transportType) { if (pdu is DataDvcBasePdu) { DataDvcBasePdu dataPdu = pdu as DataDvcBasePdu; if (channelDicbyId.ContainsKey(dataPdu.ChannelId)) { channelDicbyId[dataPdu.ChannelId].ProcessPacket(dataPdu); } } else { if (this.autoCloseChannel && (pdu is CloseDvcPdu)) { this.CloseChannel(pdu as CloseDvcPdu); return; } lock (unprocessedDVCPacketBuffer) { unprocessedDVCPacketBuffer.Add(new UnprocessedDVCPDUInfo(pdu, transportType)); } } }
/// <summary> /// Send a Dynamic virtual channel PDU /// </summary> /// <param name="pdu"></param> public void Send(DynamicVCPDU pdu) { rdpemtClient.Send(pduBuilder.ToRawData(pdu)); }
/// <summary> /// Process Packet from TCP transport /// </summary> /// <param name="pdu"></param> private void ProcessPacketFromTCP(DynamicVCPDU pdu) { ProcessPacket(pdu, DynamicVC_TransportType.RDP_TCP); }
/// <summary> /// Process packet from lossy UDP transport /// </summary> /// <param name="pdu"></param> private void ProcessPacketFromUDPL(DynamicVCPDU pdu) { ProcessPacket(pdu, DynamicVC_TransportType.RDP_UDP_Lossy); }
/// <summary> /// Process Packet from TCP transport /// </summary> /// <param name="pdu"></param> private void ProcessPacketFromTCP(DynamicVCPDU pdu) { ProcessPacket(pdu, DynamicVC_TransportType.RDP_TCP); }
/// <summary> /// Process Packet from reliable UDP transport /// </summary> /// <param name="pdu"></param> private void ProcessPacketFromUDPR(DynamicVCPDU pdu) { ProcessPacket(pdu, DynamicVC_TransportType.RDP_UDP_Reliable); }
/// <summary> /// Process packet from lossy UDP transport /// </summary> /// <param name="pdu"></param> private void ProcessPacketFromUDPL(DynamicVCPDU pdu) { ProcessPacket(pdu, DynamicVC_TransportType.RDP_UDP_Lossy); }
/// <summary> /// Send a Dynamic virtual channel PDU /// </summary> /// <param name="pdu"></param> public void Send(DynamicVCPDU pdu) { channel.Send(pduBuilder.ToRawData(pdu)); }