/// <summary> /// Expect a RDP_TUNNEL_CREATERESPONSE structure /// </summary> /// <param name="timeout"></param> /// <returns></returns> public RDP_TUNNEL_CREATERESPONSE ExpectTunnelCreateResponse(TimeSpan timeout) { if (Connected) { return(null); } DateTime endTime = DateTime.Now + timeout; RDP_TUNNEL_CREATERESPONSE createResp = null; while (DateTime.Now < endTime) { if (receiveBuffer.Count > 0) { lock (receiveBuffer) { if (receiveBuffer.Count > 0) { for (int i = 0; i < receiveBuffer.Count; i++) { if (receiveBuffer[i] is RDP_TUNNEL_CREATERESPONSE) { createResp = receiveBuffer[i] as RDP_TUNNEL_CREATERESPONSE; receiveBuffer.RemoveAt(i); return(createResp); } } } } } Thread.Sleep(waitInterval); } return(null); }
/// <summary> /// Create a RDP_TUNNEL_CREATERESPONSE pdu /// </summary> /// <param name="hrRes"></param> /// <returns></returns> public RDP_TUNNEL_CREATERESPONSE CreateTunnelCreateResponse(uint hrRes) { RDP_TUNNEL_CREATERESPONSE createRes = new RDP_TUNNEL_CREATERESPONSE(); createRes.TunnelHeader = new RDP_TUNNEL_HEADER(); createRes.TunnelHeader.Action = RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_CREATERESPONSE; createRes.TunnelHeader.Flags = 0; createRes.TunnelHeader.PayloadLength = 4; createRes.TunnelHeader.HeaderLength = 4; createRes.TunnelHeader.SubHeaders = null; createRes.HrResponse = hrRes; return createRes; }
/// <summary> /// Create a RDP_TUNNEL_CREATERESPONSE pdu /// </summary> /// <param name="hrRes"></param> /// <returns></returns> public RDP_TUNNEL_CREATERESPONSE CreateTunnelCreateResponse(uint hrRes) { RDP_TUNNEL_CREATERESPONSE createRes = new RDP_TUNNEL_CREATERESPONSE(); createRes.TunnelHeader = new RDP_TUNNEL_HEADER(); createRes.TunnelHeader.Action = RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_CREATERESPONSE; createRes.TunnelHeader.Flags = 0; createRes.TunnelHeader.PayloadLength = 4; createRes.TunnelHeader.HeaderLength = 4; createRes.TunnelHeader.SubHeaders = null; createRes.HrResponse = hrRes; return(createRes); }
/// <summary> /// Expect a RDP_TUNNEL_CREATERESPONSE structure /// </summary> /// <param name="timeout"></param> /// <returns></returns> public RDP_TUNNEL_CREATERESPONSE ExpectTunnelCreateResponse(TimeSpan timeout) { if (Connected) { return(null); } DateTime endTime = DateTime.Now + timeout; RDP_TUNNEL_CREATERESPONSE createResp = null; while (DateTime.Now < endTime) { if (receiveBuffer.Count > 0) { lock (receiveBuffer) { if (receiveBuffer.Count > 0) { for (int i = 0; i < receiveBuffer.Count; i++) { if (receiveBuffer[i] is RDP_TUNNEL_CREATERESPONSE) { createResp = receiveBuffer[i] as RDP_TUNNEL_CREATERESPONSE; receiveBuffer.RemoveAt(i); return(createResp); } } } } } if (Disconnected) { // No more packet since the connection is closed. throw new DisconnectedExcpetion(); } Thread.Sleep(waitInterval); } return(null); }
/// <summary> /// Establish a connection to server. /// </summary> /// <param name="requestId">The RequestID to be set in Tunnel Create Request PDU. </param> /// <param name="securityCooke">The SecurityCookie to be set in Tunnel Create Request PDU.</param> public bool Connect(uint requestId, byte[] securityCookie, TimeSpan timeout) { // Send a Tunnel Create Request. RDP_TUNNEL_CREATEREQUEST request = this.CreateTunnelCreateRequest(requestId, securityCookie); SendRdpemtPacket(request); // Expect a Tunnel Create Response. RDP_TUNNEL_CREATERESPONSE response = this.ExpectTunnelCreateResponse(timeout); if (null == response || response.HrResponse != HrResponse_S_OK) { return(false); } else { connected = true; return(true); } }
/// <summary> /// Expect a connection request from client. /// </summary> /// <param name="timeout">Timeout.</param> /// <param name="requestId">The requestID should be set in Tunnel Create Request.</param> /// <param name="securityCooke">The SecurityCookie should be set in Tunnel Create Request.</param> public bool ExpectConnect(TimeSpan timeout, out uint requestId, out byte[] securityCooke) { // Expect a Tunnel Create Request. RDP_TUNNEL_CREATEREQUEST createReq = this.ExpectTunnelCreateRequest(timeout); if (createReq == null) { requestId = 0; securityCooke = null; return(false); } requestId = createReq.RequestID; securityCooke = createReq.SecurityCookie; // Respond a Tunnel Create Response. RDP_TUNNEL_CREATERESPONSE createRes = this.CreateTunnelCreateResponse(HrResponse_S_OK); this.SendRdpemtPacket(createRes); connected = true; return(true); }
/// <summary> /// Call this method to decode byte array to MS-RDPEMT packets /// </summary> /// <param name="action">The action value in header</param> /// <param name="data">Data in bytes to be decoded</param> /// <returns>The decoded packet</returns> public static RdpemtBasePDU DecodeRdpemtPacket(byte[] data, ref int index) { if (data == null || data.Length - index < 4) { return null; } byte action = (byte)(0xF & data[index]); byte[] payloadLenData = new byte[2]; Array.Copy(data, index + 1, payloadLenData, 0, 2); if (!BitConverter.IsLittleEndian) { // Reverse the sequence if it is not little endian Array.Reverse(payloadLenData); } ushort payloadLength = BitConverter.ToUInt16(payloadLenData, 0); byte headerLength = data[index + 3]; int expectLen = payloadLength + headerLength; if (expectLen > data.Length) { return null; } byte[] toDecodeData = new byte[expectLen]; Array.Copy(data, index, toDecodeData, 0, expectLen); index += expectLen; RdpemtBasePDU rePdu = null; if (action == (byte)RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_CREATEREQUEST) { RDP_TUNNEL_CREATEREQUEST createReq = new RDP_TUNNEL_CREATEREQUEST(); bool bResult = PduMarshaler.Unmarshal(toDecodeData, createReq); if (bResult) { rePdu = createReq; } } else if (action == (byte)RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_CREATERESPONSE) { RDP_TUNNEL_CREATERESPONSE createRes = new RDP_TUNNEL_CREATERESPONSE(); bool bResult = PduMarshaler.Unmarshal(toDecodeData, createRes); if (bResult) { rePdu = createRes; } } else if (action == (byte)RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_DATA) { RDP_TUNNEL_DATA tunnelData = new RDP_TUNNEL_DATA(); bool bResult = PduMarshaler.Unmarshal(toDecodeData, tunnelData); if (bResult) { rePdu = tunnelData; } } else { throw new NotSupportedException("Unknow action in RDP_TUNNEL_HEADER:" + action); } if (rePdu == null) { throw new NotSupportedException("Decode for RDPEMT PDU failed, Action:" + action); } return rePdu; }
/// <summary> /// Call this method to decode byte array to MS-RDPEMT packets /// </summary> /// <param name="action">The action value in header</param> /// <param name="data">Data in bytes to be decoded</param> /// <returns>The decoded packet</returns> public static RdpemtBasePDU DecodeRdpemtPacket(byte[] data, ref int index) { if (data == null || data.Length - index < 4) { return(null); } byte action = (byte)(0xF & data[index]); byte[] payloadLenData = new byte[2]; Array.Copy(data, index + 1, payloadLenData, 0, 2); if (!BitConverter.IsLittleEndian) { // Reverse the sequence if it is not little endian Array.Reverse(payloadLenData); } ushort payloadLength = BitConverter.ToUInt16(payloadLenData, 0); byte headerLength = data[index + 3]; int expectLen = payloadLength + headerLength; if (expectLen > data.Length) { return(null); } byte[] toDecodeData = new byte[expectLen]; Array.Copy(data, index, toDecodeData, 0, expectLen); index += expectLen; RdpemtBasePDU rePdu = null; if (action == (byte)RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_CREATEREQUEST) { RDP_TUNNEL_CREATEREQUEST createReq = new RDP_TUNNEL_CREATEREQUEST(); bool bResult = PduMarshaler.Unmarshal(toDecodeData, createReq); if (bResult) { rePdu = createReq; } } else if (action == (byte)RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_CREATERESPONSE) { RDP_TUNNEL_CREATERESPONSE createRes = new RDP_TUNNEL_CREATERESPONSE(); bool bResult = PduMarshaler.Unmarshal(toDecodeData, createRes); if (bResult) { rePdu = createRes; } } else if (action == (byte)RDP_TUNNEL_ACTION_Values.RDPTUNNEL_ACTION_DATA) { RDP_TUNNEL_DATA tunnelData = new RDP_TUNNEL_DATA(); bool bResult = PduMarshaler.Unmarshal(toDecodeData, tunnelData); if (bResult) { rePdu = tunnelData; } } else { throw new NotSupportedException("Unknow action in RDP_TUNNEL_HEADER:" + action); } if (rePdu == null) { throw new NotSupportedException("Decode for RDPEMT PDU failed, Action:" + action); } return(rePdu); }