/// <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)); } } }
/// <summary> /// Expect a DYNVC_SOFT_SYNC_RESPONSE PDU. /// </summary> public SoftSyncReqDvcPDU ExpectSoftSyncReqPDU(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_UDP_Reliable) { 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 SoftSyncReqDvcPDU) { SoftSyncReqDvcPDU capReq = unprocessedDVCPacketBuffer[i].PDU as SoftSyncReqDvcPDU; unprocessedDVCPacketBuffer.RemoveAt(i); return(capReq); } } } } Thread.Sleep(this.waitInterval); } return(null); }
/// <summary> /// Establish a DVC after received a Create Request PDU /// </summary> /// <param name="createReq"></param> /// <param name="transportType"></param> /// <param name="receiveCallBack"></param> private void EstablishChannel(CreateReqDvcPdu createReq, DynamicVC_TransportType transportType, ReceiveData receiveCallBack = null) { if (channelDicbyId.ContainsKey(createReq.ChannelId)) { throw new InvalidOperationException("Cannot establish the DVC, since a channel with same channelId have been established. Channel ID is " + createReq.ChannelId); } DynamicVirtualChannel channel = new DynamicVirtualChannel(createReq.ChannelId, createReq.ChannelName, (ushort)createReq.HeaderBits.Sp, transportDic[transportType]); if (receiveCallBack != null) { // Add event method here can make sure processing the first DVC data packet channel.Received += receiveCallBack; } else { if (callBackMethodsDic != null && callBackMethodsDic.ContainsKey(createReq.ChannelName)) { channel.Received += callBackMethodsDic[createReq.ChannelName]; } } channelDicbyId.Add(createReq.ChannelId, channel); this.SendDVCCreateResponsePDU(createReq.ChannelId, 0, transportType); }
/// <summary> /// Initialize this protocol with create control and data channels. /// </summary> /// <param name="rdpedycServer">RDPEDYC Server instance</param> /// <param name="transportType">selected transport type for created channels</param> /// <returns>true if client supports this protocol; otherwise, return false.</returns> public bool ProtocolInitialize(RdpedycServer rdpedycServer, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_UDP_Reliable) { if (!rdpedycServer.IsMultipleTransportCreated(transportType)) { rdpedycServer.CreateMultipleTransport(transportType); } this.rdpefsServer = new RdpefsServer(rdpedycServer); bool success = false; // Create RDPEFS channel try { uint channelId = DynamicVirtualChannel.NewChannelId(); Dictionary <TunnelType_Value, List <uint> > channelListDic = new Dictionary <TunnelType_Value, List <uint> >(); List <uint> list = new List <uint>(); list.Add(channelId); channelListDic.Add(TunnelType_Value.TUNNELTYPE_UDPFECR, list); rdpedycServer.SoftSyncNegotiate(waitTime, channelListDic); success = rdpefsServer.CreateRdpefsDvc(waitTime, channelId); } catch (Exception e) { Site.Log.Add(LogEntryKind.Comment, "Exception occurred when creating RDPEFS channels: {1}", e.Message); } return(success); }
/// <summary> /// Create graphic dynamic virtual channel over UDP transport. /// </summary> private bool InitializeForSoftSync(DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_UDP_Reliable) { uint?channelId = null; if (!rdpedycServer.IsMultipleTransportCreated(transportType)) { rdpedycServer.CreateMultipleTransport(transportType); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect for Client Initiate Multitransport PDU to indicate that the client was able to successfully complete the multitransport initiation request."); rdpbcgrAdapter.WaitForPacket <Client_Initiate_Multitransport_Response_PDU>(waitTime); TestSite.Assert.IsTrue( rdpbcgrAdapter.SessionContext.ClientInitiateMultitransportResponsePDU.hrResponse == HrResponse_Value.S_OK, "hrResponse field should be {0}", HrResponse_Value.S_OK); channelId = DynamicVirtualChannel.NewChannelId(); List <uint> list = new List <uint>(); list.Add((uint)channelId); Dictionary <TunnelType_Value, List <uint> > channelListDic = new Dictionary <TunnelType_Value, List <uint> >(); TunnelType_Value tunnelType = TunnelType_Value.TUNNELTYPE_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { tunnelType = TunnelType_Value.TUNNELTYPE_UDPFECL; } channelListDic.Add(tunnelType, list); rdpedycServer.SoftSyncNegotiate(waitTime, channelListDic); } return(this.rdpegfxAdapter.CreateEGFXDvc(rdpedycServer, transportType, channelId)); }
/// <summary> /// Expect a Create Request PDU /// </summary> /// <param name="timeout">Timeout</param> /// <param name="transportType">out parameter: indicate which transport received this packet</param> /// <returns></returns> private CreateReqDvcPdu ExpectDVCCreateRequestPDU(TimeSpan timeout, out DynamicVC_TransportType 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 (unprocessedDVCPacketBuffer[i].PDU is CreateReqDvcPdu) { CreateReqDvcPdu pdu = unprocessedDVCPacketBuffer[i].PDU as CreateReqDvcPdu; transportType = unprocessedDVCPacketBuffer[i].TransportType; unprocessedDVCPacketBuffer.RemoveAt(i); return(pdu); } } } } Thread.Sleep(this.waitInterval); } return(null); } }
/// <summary> /// Expect a DVC Close PDU /// </summary> /// <param name="timeout">Time out</param> /// <param name="channelId">Channel ID</param> /// <param name="transportType">Transport Type</param> /// <returns></returns> private CloseDvcPdu ExpectDVCClosePDU(TimeSpan timeout, uint channelId, DynamicVC_TransportType transportType) { 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 CloseDvcPdu && (unprocessedDVCPacketBuffer[i].PDU as CloseDvcPdu).ChannelId == channelId) { CloseDvcPdu pdu = unprocessedDVCPacketBuffer[i].PDU as CloseDvcPdu; unprocessedDVCPacketBuffer.RemoveAt(i); return(pdu); } } } } Thread.Sleep(this.waitInterval); } return(null); }
/// <summary> /// Expect a DYNVC_SOFT_SYNC_RESPONSE PDU. /// </summary> private SoftSyncResDvcPdu ExpectSoftSyncResponsePDU(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 SoftSyncResDvcPdu) { SoftSyncResDvcPdu capResp = unprocessedDVCPacketBuffer[i].PDU as SoftSyncResDvcPdu; unprocessedDVCPacketBuffer.RemoveAt(i); return(capResp); } } } } Thread.Sleep(this.waitInterval); } return(null); }
/// <summary> /// Create a multitransport, RDP_UDP_reliable or RDP_UDP_Lossy /// </summary> /// <param name="transportType">Type of the transport, reliable or lossy</param> public void CreateMultipleTransport(DynamicVC_TransportType transportType) { if (transportDic.ContainsKey(transportType)) { throw new InvalidOperationException("The multiple transport have already been created:" + transportType); } Rdpemt_DVCClientTransport transport = new Rdpemt_DVCClientTransport(clientSessionContext, transportType); transport.UnhandledExceptionReceived += (ex) => { UnhandledExceptionReceived?.Invoke(ex); }; if (transportType == DynamicVC_TransportType.RDP_UDP_Reliable) { transport.Received += ProcessPacketFromUDPR; } else { transport.Received += ProcessPacketFromUDPL; } transport.EstablishTransportConnection(); transportDic.Add(transportType, transport); }
/// <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> 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); }
/// <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> /// Whether a multitransport has been created /// </summary> /// <param name="transportType"></param> /// <returns></returns> public bool IsMultipleTransportCreated(DynamicVC_TransportType transportType) { if (transportDic.ContainsKey(transportType)) { return(true); } return(false); }
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); } } } } }
/// <summary> /// Expect create channel reqeust from SUT /// </summary> /// <param name="timeout">Time span for waiting</param> /// <param name="channelName">Channel name to be created </param> /// <param name="transportType">Transport type, Tcp by default</param> /// <returns></returns> public DynamicVirtualChannel ExpectChannel(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { if (rdpedycClientStack == null) { throw new InvalidOperationException("RDPEDYC Client is required to be created before create channel!"); } DynamicVirtualChannel channel = rdpedycClientStack.ExpectChannel(timeout, SVCNameForEGT, transportType); return(channel); }
/// <summary> /// Expect the Soft-sync request from SUT /// </summary> /// <param name="timeout"></param> /// <param name="transportType"></param> /// <returns></returns> public SoftSyncReqDvcPDU ExpectSoftSyncReqPDU(TimeSpan timeout, DynamicVC_TransportType transportType) { if (rdpedycClientStack == null) { throw new InvalidOperationException("RDPEDYC Client is required to be created before expect soft sync request."); } SoftSyncReqDvcPDU pdu = this.rdpedycClientStack.ExpectSoftSyncReqPDU(timeout, transportType); return(pdu); }
/// <summary> /// Method to do capability exchange with RDP client. /// This function is recommended to be called by other test cases to do capability exchange. /// </summary> private void RDPEGFX_CapabilityExchange(DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP, bool isSoftSync = false) { this.TestSite.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(isSoftSync); this.TestSite.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEGFX ..."); bool bProtocolSupported = isSoftSync? InitializeForSoftSync(transportType) : this.rdpegfxAdapter.ProtocolInitialize(this.rdpedycServer, transportType); TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol."); this.TestSite.Log.Add(LogEntryKind.Debug, "Expecting capability advertise from client."); RDPGFX_CAPS_ADVERTISE capsAdv = this.rdpegfxAdapter.ExpectCapabilityAdvertise(); this.TestSite.Assert.IsNotNull(capsAdv, "RDPGFX_CAPS_ADVERTISE is received."); this.isH264AVC420Supported = false; this.isH264AVC444Supported = false; this.isSmallCache = false; this.TestSite.Log.Add(LogEntryKind.Debug, "Sending capability confirm to client."); // Set first capset in capability advertise request, if no capdata in request, use default flag. CapsFlags capFlag = CapsFlags.RDPGFX_CAPS_FLAG_DEFAULT; CapsVersions version = CapsVersions.RDPGFX_CAPVERSION_8; if (capsAdv.capsSetCount > 0) { foreach (RDPGFX_CAPSET capSet in capsAdv.capsSets) { CapsFlags flag = (CapsFlags)BitConverter.ToUInt32(capSet.capsData, 0); if (capSet.version >= version) { version = capSet.version; capFlag = flag; } if (capSet.version == CapsVersions.RDPGFX_CAPVERSION_81 && (flag & CapsFlags.RDPGFX_CAPS_FLAG_AVC420_ENABLED) == CapsFlags.RDPGFX_CAPS_FLAG_AVC420_ENABLED) { this.isH264AVC420Supported = true; } else if (capSet.version >= CapsVersions.RDPGFX_CAPVERSION_10 && //RDPGFX_CAPVERSION_10 and RDPGFX_CAPVERSION_102 (flag & CapsFlags.RDPGFX_CAPS_FLAG_AVC_DISABLED) == 0) { this.isH264AVC420Supported = true; this.isH264AVC444Supported = true; } if ((flag & CapsFlags.RDPGFX_CAPS_FLAG_SMALL_CACHE) == CapsFlags.RDPGFX_CAPS_FLAG_SMALL_CACHE) { this.isSmallCache = true; } } } this.rdpegfxAdapter.SendCapabilityConfirm(capFlag, version); }
/// <summary> /// Send the DYNVC_DATA_ PDU /// </summary> /// <param name="channelId"></param> /// <param name="transportType"></param> public void SendUncompressedPdu(uint channelId, DynamicVC_TransportType transportType) { // Generate the data based on TD byte[] data = new byte[ConstLength.MAX_UNCOMPRESSED_DATA_LENGTH]; for (int i = 0; i < ConstLength.MAX_UNCOMPRESSED_DATA_LENGTH; i++) { data[i] = 0x71; } channelDicbyId[channelId].Send(data, false); }
/// <summary> /// Send compressed data sequence PDU to SUT, including the DYNVC_DATA_FIST_COMPRESSED and DYNVC_DATA_COMPRESSED /// </summary> /// <param name="channelId"></param> /// <param name="transportType"></param> public void SendCompressedSequencePdu(uint channelId, DynamicVC_TransportType transportType) { if (rdpedycClientStack == null) { throw new InvalidOperationException("RDPEDYC Client is required to be created before send data!"); } this.rdpedycClientStack.SendCompressedData(channelId, transportType); return; }
private void CheckPlatformCompatibility(DynamicVC_TransportType dvcTransportType) { // Check lossy dynamic virtual channel transport type, which is currently only supported on Windows. if (dvcTransportType == DynamicVC_TransportType.RDP_UDP_Lossy) { if (!OperatingSystem.IsWindows()) { TestSite.Assume.Inconclusive("The lossy dynamic virtual channel transport type is only supported on Windows."); } } }
/// <summary> /// Create dynamic virtual channel. /// </summary> /// <param name="transportType">selected transport type for created channels</param> /// <param name="timeout">Timeout</param> /// <returns>true if client supports this protocol; otherwise, return false.</returns> public bool CreateRdpegtDvc(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { const ushort priority = 0; rdpegtDVC = rdpedycServer.CreateChannel(timeout, priority, RdpegtChannelName, transportType, null); if (rdpegtDVC != null) { return(true); } return(false); }
/// <summary> /// Construcotr /// </summary> /// <param name="clientSessionContext"></param> /// <param name="transportType"></param> public Rdpemt_DVCClientTransport(RdpbcgrClientContext clientSessionContext, DynamicVC_TransportType transportType) { this.clientSessionContext = clientSessionContext; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } decoder = new ClientDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
/// <summary> /// Send the DYNVC_DATA_FIRST_COMPRESSED and DYNCV_DATA_COMPRESSED PDU /// </summary> /// <param name="channelId"></param> /// <param name="transportType"></param> public void SendCompressedData(uint channelId, DynamicVC_TransportType transportType) { // Generate the data based on TD examples byte[] data = new byte[] { 0xe0, 0x26, 0x38, 0xc4, 0x3f, 0xf4, 0x74, 0x01 }; SendFirstCompressedDataPdu(channelId, 0x0c7b, data, transportType); // Generate the data based on TD examples data = new byte[] { 0xe0, 0x26, 0x88, 0x7f, 0xe8, 0xf4, 0x02 }; SendDataCompressedReqPdu(channelId, data, transportType); }
/// <summary> /// Establish a DVC after received a Create Request PDU /// </summary> /// <param name="createReq"></param> /// <param name="transportType"></param> /// <param name="receiveCallBack"></param> private void EstablishChannel(CreateReqDvcPdu createReq, DynamicVC_TransportType transportType, ReceiveData receiveCallBack = null) { if (channelDicbyId.ContainsKey(createReq.ChannelId)) { throw new InvalidOperationException("Cannot establish the DVC, since a channel with same channelId have been established. Channel ID is " + createReq.ChannelId); } DynamicVirtualChannel channel = new DynamicVirtualChannel(createReq.ChannelId, createReq.ChannelName, (ushort)createReq.HeaderBits.Sp, transportDic[transportType]); channelDicbyId.Add(createReq.ChannelId, channel); this.SendDVCCreateResponsePDU(createReq.ChannelId, 0, transportType); }
/// <summary> /// Create dynamic virtual channel. /// </summary> /// <param name="transportType">selected transport type for created channels</param> /// <param name="timeout">Timeout</param> /// <returns>true if client supports this protocol; otherwise, return false.</returns> public bool CreateRdpevorDvc(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { const ushort priority = 0; rdpevorControlDVC = rdpedycServer.CreateChannel(timeout, priority, RdpevorControlChannelName, transportType, OnDataReceived); rdpevorDataDVC = rdpedycServer.CreateChannel(timeout, priority, RdpevorDataChannelName, transportType, OnDataReceived); if (rdpevorControlDVC != null && rdpevorDataDVC != null) { return(true); } return(false); }
/// <summary> /// Construcotr /// </summary> /// <param name="clientSessionContext"></param> /// <param name="transportType"></param> public Rdpemt_DVCClientTransport(RdpbcgrClientContext clientSessionContext, DynamicVC_TransportType transportType) { this.clientSessionContext = clientSessionContext; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } EstablishTransportConnection(); decoder = new ClientDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
private void RDPEGFX_CacheManagement(DynamicVC_TransportType transport, bool isSoftSync) { // Check if SUT supports Soft Sync. if (isSoftSync) { this.TestSite.Assert.IsTrue(isClientSupportSoftSync, "SUT should support Soft-Sync."); } // Init for capability exchange RDPEGFX_CapabilityExchange(transport, isSoftSync); // Create a surface RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight); Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888); this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id); // Build muliple cache to surface messages to cover the surface by cacheRect ushort cacheW = (ushort)(RdpegfxTestUtility.cacheRect.right - RdpegfxTestUtility.cacheRect.left); ushort cacheH = (ushort)(RdpegfxTestUtility.cacheRect.bottom - RdpegfxTestUtility.cacheRect.top); ushort currRectTop = 0; List <RDPGFX_POINT16> destPointList = new List <RDPGFX_POINT16>(); while (currRectTop < surf.Height) { ushort currRectLeft = 0; while (currRectLeft < surf.Width) { RDPGFX_POINT16 pos = new RDPGFX_POINT16(currRectLeft, currRectTop); destPointList.Add(pos); currRectLeft += cacheW; } currRectTop += cacheH; } uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), null, RdpegfxTestUtility.fillColorRed); this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}", fid); this.rdpegfxAdapter.ExpectFrameAck(fid); this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true."); this.VerifySUTDisplay(false, surfRect); // Delete the surface after wait 3 seconds. this.rdpegfxAdapter.DeleteSurface(surf.Id); this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id); }
/// <summary> /// Wait for creation of dynamic virtual channel for RDPEGFX /// </summary> /// <param name="timeout"></param> /// <param name="transportType"></param> /// <returns></returns> public bool WaitForRdpegfxDvcCreation(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { try { rdpeiDVC = rdpedycClient.ExpectChannel(timeout, rdpeiChannelName, transportType, OnDataReceived); } catch { } if (rdpeiDVC != null) { return(true); } return(false); }
/// <summary> /// Wait for creation of dynamic virtual channel for RDPEGFX /// </summary> /// <param name="timeout"></param> /// <param name="transportType"></param> /// <returns></returns> public bool WaitForRdpegfxDvcCreation(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { try { RdpegfxDVC = rdpedycClient.ExpectChannel(timeout, RdpegfxGraphicChannelName, transportType); } catch { } if (RdpegfxDVC != null) { return(true); } return(false); }
/// <summary> /// Wait for creation of dynamic virtual channel for RDPEVOR /// </summary> /// <param name="timeout"></param> /// <param name="transportType"></param> /// <returns></returns> public bool WaitForRdpevorDvcCreation(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { try { rdpevorControlDVC = rdpedycClient.ExpectChannel(timeout, RdpevorControlChannelName, transportType); rdpevorDataDVC = rdpedycClient.ExpectChannel(timeout, RdpevorDataChannelName, transportType); } catch { } if (rdpevorControlDVC != null && rdpevorDataDVC != null) { return(true); } return(false); }
/// <summary> /// Constructor /// </summary> /// <param name="connectedRdpServer"></param> /// <param name="context"></param> /// <param name="transportType"></param> public Rdpemt_DVCServerTransport(RdpbcgrServer connectedRdpServer, RdpbcgrServerSessionContext context, DynamicVC_TransportType transportType) { this.serverSessionContext = context; this.rdpbcgrServer = connectedRdpServer; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } if (!serverSessionContext.IsClientMultitransportChannelDataRecieved) { throw new NotSupportedException("This RDP connection doesn't support multiple transport!"); } EstablishTransportConnection(); decoder = new ServerDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
/// <summary> /// Initialize this protocol with create control and data channels. /// </summary> /// <param name="rdpedycServer">RDPEDYC Server instance</param> /// <param name="transportType">selected transport type for created channels</param> /// <returns>true if client supports this protocol; otherwise, return false.</returns> public bool ProtocolInitialize(RdpedycServer rdpedycServer, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { if (!rdpedycServer.IsMultipleTransportCreated(transportType)) { rdpedycServer.CreateMultipleTransport(transportType); } this.rdpegtServer = new RdpegtServer(rdpedycServer); bool success = false; // Create RDPEGT Channel try { success = rdpegtServer.CreateRdpegtDvc(waitTime); } catch (Exception e) { Site.Log.Add(LogEntryKind.Comment, "Exception occurred when creating RDPEGT channels: {1}", e.Message); } return success; }
/// <summary> /// Creates a dynamic virtual channel with specified channel ID. /// </summary> /// <param name="transportType">selected transport type for created channels</param> /// <returns>Instance of the DVC created</returns> public DynamicVirtualChannel CreateVirtualChannel(DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { if (!this.rdpedycServer.IsMultipleTransportCreated(transportType)) { this.rdpedycServer.CreateMultipleTransport(transportType); } DynamicVirtualChannel rdpeusbDVC = null; try { rdpeusbDVC = this.rdpeusbServer.CreateRdpeusbDvc(waitTime, transportType); } catch (Exception e) { Site.Assert.Fail("Exception occurred when creating RDPEUSB channel: {0}.", e.Message); } return rdpeusbDVC; }
/// <summary> /// Send DVC Close PDU /// </summary> /// <param name="channelId">Channel Id</param> /// <param name="transportType">Transport Type</param> private void SendDVCClosePDU(uint channelId, DynamicVC_TransportType transportType) { CloseDvcPdu pdu = pduBuilder.CreateCloseDvcPdu(channelId); this.Send(pdu, transportType); }
private void RDPEGFX_CacheManagement(DynamicVC_TransportType transport, bool isSoftSync) { // Check if SUT supports Soft Sync. if(isSoftSync) this.TestSite.Assert.IsTrue(isClientSupportSoftSync, "SUT should support Soft-Sync."); // Init for capability exchange RDPEGFX_CapabilityExchange(transport, isSoftSync); // Create a surface RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight); Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888); this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id); // Build muliple cache to surface messages to cover the surface by cacheRect ushort cacheW = (ushort)(RdpegfxTestUtility.cacheRect.right - RdpegfxTestUtility.cacheRect.left); ushort cacheH = (ushort)(RdpegfxTestUtility.cacheRect.bottom - RdpegfxTestUtility.cacheRect.top); ushort currRectTop = 0; List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>(); while (currRectTop < surf.Height) { ushort currRectLeft = 0; while (currRectLeft < surf.Width) { RDPGFX_POINT16 pos = new RDPGFX_POINT16(currRectLeft, currRectTop); destPointList.Add(pos); currRectLeft += cacheW; } currRectTop += cacheH; } uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), null, RdpegfxTestUtility.fillColorRed); this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}", fid); this.rdpegfxAdapter.ExpectFrameAck(fid); this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true."); this.VerifySUTDisplay(false, surfRect); // Delete the surface after wait 3 seconds. this.rdpegfxAdapter.DeleteSurface(surf.Id); this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id); }
/// <summary> /// Expect a Create Request PDU /// </summary> /// <param name="timeout">Timeout</param> /// <param name="transportType">out parameter: indicate which transport received this packet</param> /// <returns></returns> private CreateReqDvcPdu ExpectDVCCreateRequestPDU(TimeSpan timeout, out DynamicVC_TransportType transportType) { transportType = DynamicVC_TransportType.RDP_TCP; { DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { if (unprocessedDVCPacketBuffer.Count > 0) { lock (unprocessedDVCPacketBuffer) { if (unprocessedDVCPacketBuffer.Count > 0) { for (int i = 0; i < unprocessedDVCPacketBuffer.Count; i++) { if (unprocessedDVCPacketBuffer[i].PDU is CreateReqDvcPdu) { CreateReqDvcPdu pdu = unprocessedDVCPacketBuffer[i].PDU as CreateReqDvcPdu; transportType = unprocessedDVCPacketBuffer[i].TransportType; unprocessedDVCPacketBuffer.RemoveAt(i); return pdu; } } } } } Thread.Sleep(this.waitInterval); } return null; } }
/// <summary> /// Send a DVC Create Response PDU /// </summary> /// <param name="channelId"></param> /// <param name="creationStatus"></param> /// <param name="transportType"></param> private void SendDVCCreateResponsePDU(uint channelId, int creationStatus, DynamicVC_TransportType transportType) { CreateRespDvcPdu createResp = pduBuilder.CreateCreateRespDvcPdu(channelId, creationStatus); this.Send(createResp, transportType); }
/// <summary> /// Method to do capability exchange with RDP client. /// This function is recommended to be called by other test cases to do capability exchange. /// </summary> private void RDPEGFX_CapabilityExchange(DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP, bool isSoftSync = false) { this.TestSite.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(isSoftSync); this.TestSite.Log.Add(LogEntryKind.Debug, "Creating dynamic virtual channels for MS-RDPEGFX ..."); bool bProtocolSupported = isSoftSync? InitializeForSoftSync(transportType) : this.rdpegfxAdapter.ProtocolInitialize(this.rdpedycServer, transportType); TestSite.Assert.IsTrue(bProtocolSupported, "Client should support this protocol."); this.TestSite.Log.Add(LogEntryKind.Debug, "Expecting capability advertise from client."); RDPGFX_CAPS_ADVERTISE capsAdv = this.rdpegfxAdapter.ExpectCapabilityAdvertise(); this.TestSite.Assert.IsNotNull(capsAdv, "RDPGFX_CAPS_ADVERTISE is received."); this.isH264AVC420Supported = false; this.isH264AVC444Supported = false; this.isSmallCache = false; this.TestSite.Log.Add(LogEntryKind.Debug, "Sending capability confirm to client."); // Set first capset in capability advertise request, if no capdata in request, use default flag. CapsFlags capFlag = CapsFlags.RDPGFX_CAPS_FLAG_DEFAULT; CapsVersions version = CapsVersions.RDPGFX_CAPVERSION_8; if (capsAdv.capsSetCount > 0) { foreach (RDPGFX_CAPSET capSet in capsAdv.capsSets) { CapsFlags flag = (CapsFlags)BitConverter.ToUInt32(capSet.capsData, 0); if (capSet.version >= version) { version = capSet.version; capFlag = flag; } if (capSet.version == CapsVersions.RDPGFX_CAPVERSION_81 && (flag & CapsFlags.RDPGFX_CAPS_FLAG_AVC420_ENABLED) == CapsFlags.RDPGFX_CAPS_FLAG_AVC420_ENABLED) { this.isH264AVC420Supported = true; } else if (capSet.version >= CapsVersions.RDPGFX_CAPVERSION_10 //RDPGFX_CAPVERSION_10 and RDPGFX_CAPVERSION_102 && (flag & CapsFlags.RDPGFX_CAPS_FLAG_AVC_DISABLED) == 0) { this.isH264AVC420Supported = true; this.isH264AVC444Supported = true; } if ((flag & CapsFlags.RDPGFX_CAPS_FLAG_SMALL_CACHE) == CapsFlags.RDPGFX_CAPS_FLAG_SMALL_CACHE) { this.isSmallCache = true; } } } this.rdpegfxAdapter.SendCapabilityConfirm(capFlag, version); }
/// <summary> /// Expect a DVC Create Response PDU /// </summary> /// <param name="timeout">Timeout</param> /// <param name="channelId">Channel Id</param> /// <param name="transportType">Transport type</param> /// <returns></returns> private CreateRespDvcPdu ExpectDVCCreateResponsePDU(TimeSpan timeout, uint channelId, DynamicVC_TransportType transportType) { DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { if (unprocessedDVCPacketBuffer.Count > 0) { lock (unprocessedDVCPacketBuffer) { if (unprocessedDVCPacketBuffer.Count > 0) { for (int i = 0; i < unprocessedDVCPacketBuffer.Count; i++) { if (transportType == unprocessedDVCPacketBuffer[i].TransportType && unprocessedDVCPacketBuffer[i].PDU is CreateRespDvcPdu && (unprocessedDVCPacketBuffer[i].PDU as CreateRespDvcPdu).ChannelId == channelId) { CreateRespDvcPdu pdu = unprocessedDVCPacketBuffer[i].PDU as CreateRespDvcPdu; unprocessedDVCPacketBuffer.RemoveAt(i); return pdu; } } } } } 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 (this.autoCloseChannel && (pdu is CloseDvcPdu)) { this.CloseChannel(pdu as CloseDvcPdu); return; } lock (unprocessedDVCPacketBuffer) { unprocessedDVCPacketBuffer.Add(new UnprocessedDVCPDUInfo(pdu, transportType)); } } }
/// <summary> /// Wait for creation of dynamic virtual channel for RDPEGT /// </summary> /// <param name="timeout"></param> /// <param name="transportType"></param> /// <returns></returns> public bool WaitForRdpegtDvcCreation(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { try { rdpegtDVC = rdpedycClient.ExpectChannel(timeout, RdpegtChannelName, transportType, OnDataReceived); } catch { } if (rdpegtDVC != null) { return true; } return false; }
public UnprocessedDVCPDUInfo(DynamicVCPDU pdu, DynamicVC_TransportType type) { this.PDU = pdu; this.TransportType = type; }
/// <summary> /// Send DYNVC_SOFT_SYNC_REQUEST PDU. /// </summary> private void SendSoftSyncRequestPDU(SoftSyncReqFlags_Value flags, ushort numberOfTunnels = 0, SoftSyncChannelList[] channelList = null, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { SoftSyncReqDvcPDU pdu = pduBuilder.CreateSoftSyncReqPdu(flags, numberOfTunnels, channelList); this.Send(pdu, transportType); }
/// <summary> /// Send a Create Request PDU /// </summary> /// <param name="priority">Priority</param> /// <param name="channelId">Channel ID</param> /// <param name="channelName">Channel Name</param> /// <param name="transportType">Transport type</param> private void SendDVCCreateRequestPDU(ushort priority, uint channelId, string channelName, DynamicVC_TransportType transportType) { CreateReqDvcPdu pdu = pduBuilder.CreateCreateReqDvcPdu(priority, channelId, channelName); this.Send(pdu, transportType); }
/// <summary> /// Create dynamic virtual channel. /// </summary> /// <param name="transportType">selected transport type for created channels</param> /// <param name="timeout">Timeout</param> /// <returns>true if client supports this protocol; otherwise, return false.</returns> public bool CreateRdpegtDvc(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { const ushort priority = 0; rdpegtDVC = rdpedycServer.CreateChannel(timeout, priority, RdpegtChannelName, transportType, null); if (rdpegtDVC != null) { return true; } return false; }
/// <summary> /// Whether a multitransport has been created /// </summary> /// <param name="transportType"></param> /// <returns></returns> public bool IsMultipleTransportCreated(DynamicVC_TransportType transportType) { if (transportDic.ContainsKey(transportType)) { return true; } return false; }
/// <summary> /// Create graphic dynamic virtual channel over UDP transport. /// </summary> private bool InitializeForSoftSync(DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_UDP_Reliable) { uint? channelId = null; if (!rdpedycServer.IsMultipleTransportCreated(transportType)) { rdpedycServer.CreateMultipleTransport(transportType); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect for Client Initiate Multitransport PDU to indicate that the client was able to successfully complete the multitransport initiation request."); rdpbcgrAdapter.WaitForPacket<Client_Initiate_Multitransport_Response_PDU>(waitTime); TestSite.Assert.IsTrue( rdpbcgrAdapter.SessionContext.ClientInitiateMultitransportResponsePDU.hrResponse == HrResponse_Value.S_OK, "hrResponse field should be {0}", HrResponse_Value.S_OK); channelId = DynamicVirtualChannel.NewChannelId(); List<uint> list = new List<uint>(); list.Add((uint)channelId); Dictionary<TunnelType_Value, List<uint>> channelListDic = new Dictionary<TunnelType_Value, List<uint>>(); TunnelType_Value tunnelType = TunnelType_Value.TUNNELTYPE_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { tunnelType = TunnelType_Value.TUNNELTYPE_UDPFECL; } channelListDic.Add(tunnelType, list); rdpedycServer.SoftSyncNegotiate(waitTime, channelListDic); } return this.rdpegfxAdapter.CreateEGFXDvc(rdpedycServer, transportType, channelId); }
/// <summary> /// Create graphic DVC channel. /// </summary> /// <param name="rdpedycServer">RDPEDYC server instance</param> /// <param name="transportType">Transport type</param> /// <param name="channelId">Channel Id</param> /// <returns>True if success; otherwise, return false.</returns> public bool CreateEGFXDvc(RdpedycServer rdpedycServer, DynamicVC_TransportType transportType, uint? channelId = null) { this.egfxServer = new RdpegfxServer(rdpedycServer); bool success = false; try { success = egfxServer.CreateRdpegfxDvc(waitTime, transportType, channelId); } catch (Exception e) { Site.Log.Add(LogEntryKind.Comment, "Exception occurred when creating RDPEGFX channel: {0}.", e.Message); } return success; }
/// <summary> /// Send a DVC Capabilities Response PDU /// </summary> /// <param name="version">Version</param> /// <param name="transportType">Transport Type</param> private void SendDVCCapResponsePDU(DYNVC_CAPS_Version version, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { CapsRespDvcPdu capResp = pduBuilder.CreateCapsRespPdu((ushort)version); this.Send(capResp, transportType); }
/// <summary> /// Initialize this protocol with create graphic DVC channels. /// </summary> /// <param name="rdpedycServer">RDPEDYC server instance</param> /// <param name="transportType">Transport type</param> /// <returns>True if client supports this protocol; otherwise, return false.</returns> public bool ProtocolInitialize(RdpedycServer rdpedycServer, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { if (!rdpedycServer.IsMultipleTransportCreated(transportType)) { rdpedycServer.CreateMultipleTransport(transportType); } return CreateEGFXDvc(rdpedycServer, transportType); }
/// <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) { if (unprocessedDVCPacketBuffer.Count > 0) { 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> /// Create a multitransport, RDP_UDP_reliable or RDP_UDP_Lossy /// </summary> /// <param name="transportType">Type of the transport, reliable or lossy</param> public void CreateMultipleTransport(DynamicVC_TransportType transportType) { if (transportDic.ContainsKey(transportType)) { throw new InvalidOperationException("The multiple transport have already been created:" + transportType); } Rdpemt_DVCServerTransport transport = new Rdpemt_DVCServerTransport(rdpbcgrServer, sessionContext, transportType); if (transportType == DynamicVC_TransportType.RDP_UDP_Reliable) { transport.Received += ProcessPacketFromUDPR; } else { transport.Received += ProcessPacketFromUDPL; } transportDic.Add(transportType, transport); }
/// <summary> /// Expect to create a SVC /// </summary> /// <param name="timeout">Timeout</param> /// <param name="channelName">Channel Name</param> /// <param name="transportType">Transport Type</param> /// <returns></returns> public DynamicVirtualChannel ExpectChannel(TimeSpan timeout, string channelName, DynamicVC_TransportType transportType, ReceiveData receiveCallBack = null) { if (autoCreateChannel) { throw new InvalidOperationException("Cannot establish a DVC manually if autoCreateChannel is true!"); } if (!transportDic.ContainsKey(transportType)) { throw new InvalidOperationException("Not create DVC transport:" + transportType); } CreateReqDvcPdu createReq = this.ExpectDVCCreateRequestPDU(timeout, channelName, transportType); if (createReq == null) { throw new System.IO.IOException("Creation of channel: " + channelName + " failed, cannot receive a Create Request PDU"); } DynamicVirtualChannel channel = new DynamicVirtualChannel(createReq.ChannelId, channelName, (ushort)createReq.HeaderBits.Sp, transportDic[transportType]); if (receiveCallBack != null) { // Add event method here can make sure processing the first DVC data packet channel.Received += receiveCallBack; } else { if (callBackMethodsDic != null && callBackMethodsDic.ContainsKey(channelName)) { channel.Received += callBackMethodsDic[channelName]; } } channelDicbyId.Add(createReq.ChannelId, channel); this.SendDVCCreateResponsePDU(createReq.ChannelId, 0, transportType); return channel; }
/// <summary> /// Create a dynamic virtual channel /// </summary> /// <param name="priority">Priority</param> /// <param name="channelName">Channel name</param> /// <param name="transportType">Transport type</param> /// <param name="receiveCallBack">Callback method called when received data</param> /// <returns>DVC created</returns> public DynamicVirtualChannel CreateChannel(TimeSpan timeout, ushort priority, string channelName, DynamicVC_TransportType transportType, ReceiveData receiveCallBack = null, uint? channelId = null) { if (!transportDic.ContainsKey(transportType)) { throw new InvalidOperationException("Not create DVC transport:" + transportType); } if (channelId == null) channelId = DynamicVirtualChannel.NewChannelId(); DynamicVirtualChannel channel = new DynamicVirtualChannel((UInt32)channelId, channelName, priority, transportDic[transportType]); if (receiveCallBack != null) { // Add event method here can make sure processing the first DVC data packet channel.Received += receiveCallBack; } channelDicbyId.Add((UInt32)channelId, channel); this.SendDVCCreateRequestPDU(priority, (UInt32)channelId, channelName, transportType); CreateRespDvcPdu createResp = this.ExpectDVCCreateResponsePDU(timeout, (UInt32)channelId, transportType); if (createResp == null) { throw new System.IO.IOException("Creation of channel: " + channelName + " failed, cannot receive a Create Response PDU"); } if (createResp.CreationStatus < 0) { //Create failed throw new System.IO.IOException("Creation of DVC failed with error code: " + createResp.CreationStatus + ", channel name is " + channelName); } return channel; }
/// <summary> /// Expect a DYNVC_SOFT_SYNC_RESPONSE PDU. /// </summary> private SoftSyncResDvcPdu ExpectSoftSyncResponsePDU(TimeSpan timeout, DynamicVC_TransportType transportType = DynamicVC_TransportType.RDP_TCP) { DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { if (unprocessedDVCPacketBuffer.Count > 0) { lock (unprocessedDVCPacketBuffer) { if (unprocessedDVCPacketBuffer.Count > 0) { for (int i = 0; i < unprocessedDVCPacketBuffer.Count; i++) { if (transportType == unprocessedDVCPacketBuffer[i].TransportType && unprocessedDVCPacketBuffer[i].PDU is SoftSyncResDvcPdu) { SoftSyncResDvcPdu capResp = unprocessedDVCPacketBuffer[i].PDU as SoftSyncResDvcPdu; unprocessedDVCPacketBuffer.RemoveAt(i); return capResp; } } } } } Thread.Sleep(this.waitInterval); } return null; }
/// <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); }