/// <summary>
        /// Clear all the members except the reconnection relative members.
        /// </summary>
        internal void ClearForReconnect()
        {
            lock (contextLock)
            {
                x224ConnectionRequestPdu = null;
                x224ConnectionConfirmPdu = null;
                x224NegotiateFailurePdu = null;
                mcsConnectInitialPdu = null;
                mcsConnectResponsePdu = null;
                userChannelId = 0;
                ioChannelId = 0;
                serverChannelId = 0;
                clientInfo = null;
                securityExchangePdu = null;
                licenseErrorPdu = null;
                demandActivePdu = null;
                comfirmActivePdu = null;
                logonInfoV1 = new TS_LOGON_INFO();
                logonInfoV2 = new TS_LOGON_INFO_VERSION_2();
                logonErrorsInfo = null;
                encryptionCount = 0;
                decryptionCount = 0;

                if (encryptionAlgorithm != null)
                {
                    encryptionAlgorithm.Dispose();
                    encryptionAlgorithm = null;
                }

                if (ioDecompressor != null)
                {
                    ioDecompressor.Dispose();
                    ioDecompressor = null;
                }

                if (ioCompressor != null)
                {
                    ioCompressor.Dispose();
                    ioCompressor = null;
                }
            }
        }
        /// <summary>
        /// Update some members of context with the specified pdu.
        /// </summary>
        /// <param name="pdu">The sending or receiving pdu.</param>
        public void UpdateContext(StackPacket pdu)
        {
            lock (contextLock)
            {
                if (!isSwitchOn)
                {
                    // Don't update context but wait for upper layer TSD to do so.
                    return;
                }

                if (pdu.GetType() == typeof(Client_X_224_Connection_Request_Pdu))
                {
                    x224ConnectionRequestPdu = (Client_X_224_Connection_Request_Pdu)pdu.Clone();
                }
                else if (pdu.GetType() == typeof(Server_X_224_Connection_Confirm_Pdu))
                {
                    x224ConnectionConfirmPdu = ((Server_X_224_Connection_Confirm_Pdu)pdu.Clone()).rdpNegData;
                }
                else if (pdu.GetType() == typeof(Server_X_224_Negotiate_Failure_Pdu))
                {
                    x224NegotiateFailurePdu = ((Server_X_224_Negotiate_Failure_Pdu)pdu.Clone()).rdpNegFailure;
                }
                else if (pdu.GetType() == typeof(Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request))
                {
                    mcsConnectInitialPdu = ((Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request)
                        pdu.Clone()).mcsCi;
                }
                else if (pdu is Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response)
                {
                    mcsConnectResponsePdu = (Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response)
                        pdu.Clone();
                    serverRandom = RdpbcgrUtility.CloneByteArray(mcsConnectResponsePdu.mcsCrsp.gccPdu.serverSecurityData.serverRandom);
                    ioChannelId = mcsConnectResponsePdu.mcsCrsp.gccPdu.serverNetworkData.MCSChannelId;
                    if(mcsConnectResponsePdu.mcsCrsp.gccPdu.serverMessageChannelData != null)
                        mcsMsgChannelId = mcsConnectResponsePdu.mcsCrsp.gccPdu.serverMessageChannelData.MCSChannelID;
                    encryptionAlgorithm = new EncryptionAlgorithm(RdpEncryptionMethod);
                }
                else if (pdu.GetType() == typeof(Server_MCS_Attach_User_Confirm_Pdu))
                {
                    if (((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator != null)
                    {
                        userChannelId = (ushort)((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator.Value;
                    }
                }
                else if (pdu.GetType() == typeof(Client_Security_Exchange_Pdu))
                {
                    securityExchangePdu = (Client_Security_Exchange_Pdu)pdu.Clone();
                    clientRandom = RdpbcgrUtility.CloneByteArray(
                        ((Client_Security_Exchange_Pdu)pdu).securityExchangePduData.clientRandom);
                    GenerateSessionKey();
                }
                else if (pdu.GetType() == typeof(Client_Info_Pdu))
                {
                    clientInfo = ((Client_Info_Pdu)pdu.Clone()).infoPacket;
                    if (clientInfo != null
                        && (clientInfo.flags & flags_Values.INFO_COMPRESSION) == flags_Values.INFO_COMPRESSION)
                    {
                        ioDecompressor = new Decompressor(SlidingWindowSize.EightKB);
                        ioCompressor = new Compressor(SlidingWindowSize.EightKB);
                    }
                    isWaitingLicenseErrorPdu = true;
                }
                else if (pdu.GetType() == typeof(Server_Auto_Detect_Request_PDU))
                {

                    NETWORK_DETECTION_REQUEST requestData = ((Server_Auto_Detect_Request_PDU)pdu).autoDetectReqData.Clone();
                    if (requestData.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_IN_CONNECTTIME || requestData.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME)
                    {
                        RDP_RTT_REQUEST rttRequest = (RDP_RTT_REQUEST)requestData;
                        rttRequest.sendTime = DateTime.Now;
                        this.serverAutoDetectRequestData.Add(rttRequest.sequenceNumber, rttRequest);
                    }
                }
                else if (pdu.GetType() == typeof(Client_Auto_Detect_Response_PDU))
                {
                    clientAutoDetectResponsePdu = (Client_Auto_Detect_Response_PDU)pdu.Clone();
                    NETWORK_DETECTION_RESPONSE responseData = clientAutoDetectResponsePdu.autodetectRspPduData;
                    if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_RTT_RESPONSE)
                    {
                        RDP_RTT_REQUEST rttRequest = (RDP_RTT_REQUEST)serverAutoDetectRequestData[responseData.sequenceNumber];
                        if (rttRequest != null)
                        {
                            TimeSpan interval = DateTime.Now -  rttRequest.sendTime;
                            this.autoDetectedRTTList.Add((uint)interval.TotalMilliseconds);
                            serverAutoDetectRequestData.Remove(responseData.sequenceNumber);
                        }
                    }
                    else if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_AFTER_CONNECT || responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_DURING_CONNECT)
                    {
                        RDP_BW_RESULTS bwResult = (RDP_BW_RESULTS)responseData;
                        if(bwResult.timeDelta != 0)
                            this.autoDetectedBandwidth = (uint)(bwResult.byteCount / bwResult.timeDelta);
                    }
                    else if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_NETCHAR_SYNC)
                    {
                        RDP_NETCHAR_SYNC netSync = (RDP_NETCHAR_SYNC)responseData;
                        this.autoDetectedRTTList.Add(netSync.rtt);
                        this.autoDetectedBandwidth = netSync.bandwidth;
                    }
                }
                else if (pdu.GetType() == typeof(Server_License_Error_Pdu_Valid_Client))
                {
                    licenseErrorPdu = (Server_License_Error_Pdu_Valid_Client)pdu.Clone();
                    serverChannelId = licenseErrorPdu.commonHeader.initiator;
                }
                else if (pdu.GetType() == typeof(Server_Initiate_Multitransport_Request_PDU))
                {
                    Server_Initiate_Multitransport_Request_PDU requestPDU = (Server_Initiate_Multitransport_Request_PDU)pdu;
                    serverInitiateMultitransportRequestPduDictionary.Add(requestPDU.requestId, requestPDU);
                }
                else if (pdu.GetType() == typeof(Client_Initiate_Multitransport_Response_PDU))
                {
                    clientInitiateMultitransportResponsePdu = (Client_Initiate_Multitransport_Response_PDU)pdu;
                }
                else if (pdu.GetType() == typeof(Server_Demand_Active_Pdu))
                {
                    serverChannelId = ((Server_Demand_Active_Pdu)pdu.Clone()).commonHeader.initiator;
                    demandActivePdu = ((Server_Demand_Active_Pdu)pdu.Clone()).demandActivePduData;

                }
                else if (pdu.GetType() == typeof(Client_Confirm_Active_Pdu))
                {
                    comfirmActivePdu = ((Client_Confirm_Active_Pdu)pdu.Clone()).confirmActivePduData;
                    if (channelManager == null)
                    {
                        channelManager = new ServerStaticVirtualChannelManager(this);
                    }
                }
                else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Server_Pdu))
                {
                    lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Server_Pdu)
                        pdu).disconnectProvider.reason.Value;
                }
                else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Pdu))
                {
                    lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Pdu)
                        pdu).disconnectProvider.reason.Value;
                }
                else if (pdu.GetType() == typeof(Server_Set_Error_Info_Pdu))
                {
                    lastErrorInfo = ((Server_Set_Error_Info_Pdu)pdu).errorInfoPduData.errorInfo;
                }
                else if (pdu.GetType() == typeof(Server_Status_Info_Pdu))
                {
                    lastStatusInfo = ((Server_Status_Info_Pdu)pdu).statusCode;
                }
                else if (pdu.GetType() == typeof(Server_Save_Session_Info_Pdu))
                {
                    Server_Save_Session_Info_Pdu saveSessionInfoPdu = (Server_Save_Session_Info_Pdu)pdu.Clone();

                    switch (saveSessionInfoPdu.saveSessionInfoPduData.infoType)
                    {
                        case infoType_Values.INFOTYPE_LOGON:
                            logonInfoV1 = (TS_LOGON_INFO)saveSessionInfoPdu.saveSessionInfoPduData.infoData;
                            break;

                        case infoType_Values.INFOTYPE_LOGON_LONG:
                            logonInfoV2 = (TS_LOGON_INFO_VERSION_2)saveSessionInfoPdu.saveSessionInfoPduData.infoData;
                            break;

                        case infoType_Values.INFOTYPE_LOGON_EXTENDED_INF:
                            TS_LOGON_INFO_EXTENDED infoExtended =
                                (TS_LOGON_INFO_EXTENDED)saveSessionInfoPdu.saveSessionInfoPduData.infoData;
                            switch (infoExtended.FieldsPresent)
                            {
                                case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE
                                   | FieldsPresent_Values.LOGON_EX_LOGONERRORS:
                                    autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData;
                                    logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[1].FieldData;
                                    break;

                                case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE:
                                    autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData;
                                    break;

                                case FieldsPresent_Values.LOGON_EX_LOGONERRORS:
                                    logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[0].FieldData;
                                    break;

                                default:
                                    break;
                            }
                            break;

                        default:
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// Update some members of context with the specified pdu.
        /// </summary>
        /// <param name="pdu">The sending or receiving pdu.</param>
        public void UpdateContext(StackPacket pdu)
        {
            lock (contextLock)
            {
                if (!isSwitchOn)
                {
                    // Don't update context but wait for upper layer TSD to do so.
                    return;
                }

                if (pdu.GetType() == typeof(Client_X_224_Connection_Request_Pdu))
                {
                    x224ConnectionRequestPdu = (Client_X_224_Connection_Request_Pdu)pdu.Clone();
                }
                else if (pdu.GetType() == typeof(Server_X_224_Connection_Confirm_Pdu))
                {
                    x224ConnectionConfirmPdu = ((Server_X_224_Connection_Confirm_Pdu)pdu.Clone()).rdpNegData;
                }
                else if (pdu.GetType() == typeof(Server_X_224_Negotiate_Failure_Pdu))
                {
                    x224NegotiateFailurePdu = ((Server_X_224_Negotiate_Failure_Pdu)pdu.Clone()).rdpNegFailure;
                }
                else if (pdu.GetType() == typeof(Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request))
                {
                    mcsConnectInitialPdu = ((Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request)
                        pdu.Clone()).mcsCi;
                }
                else if (pdu.GetType() == typeof(Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response))
                {
                    mcsConnectResponsePdu = (Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response)
                        pdu.Clone();
                    encryptionAlgorithm = new EncryptionAlgorithm(RdpEncryptionMethod);
                }
                else if (pdu.GetType() == typeof(Server_MCS_Attach_User_Confirm_Pdu))
                {
                    userChannelId = (long)((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator.Value;
                }
                else if (pdu.GetType() == typeof(Client_Security_Exchange_Pdu))
                {
                    clientRandom = RdpbcgrUtility.CloneByteArray(
                        ((Client_Security_Exchange_Pdu)pdu).securityExchangePduData.clientRandom);
                }
                else if (pdu.GetType() == typeof(Client_Info_Pdu))
                {
                    clientInfo = ((Client_Info_Pdu)pdu.Clone()).infoPacket;
                    if (clientInfo != null
                        && (clientInfo.flags & flags_Values.INFO_COMPRESSION) == flags_Values.INFO_COMPRESSION)
                    {
                        ioDecompressor = new Decompressor((SlidingWindowSize)CompressionTypeSupported);
                    }
                }
                else if (pdu.GetType() == typeof(Server_License_Error_Pdu_Valid_Client))
                {
                    licenseErrorPdu = (Server_License_Error_Pdu_Valid_Client)pdu.Clone();
                }
                else if (pdu.GetType() == typeof(Server_Initiate_Multitransport_Request_PDU))
                {
                    Server_Initiate_Multitransport_Request_PDU initRequset = pdu as Server_Initiate_Multitransport_Request_PDU;
                    if (initRequset.requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR)
                    {
                        requestIdReliable = initRequset.requestId;
                        cookieReliable = initRequset.securityCookie;
                    }
                    else
                    {
                        requestIdLossy = initRequset.requestId;
                        cookieLossy = initRequset.securityCookie;
                    }
                }
                else if (pdu.GetType() == typeof(Server_Demand_Active_Pdu))
                {
                    demandActivePdu = ((Server_Demand_Active_Pdu)pdu.Clone()).demandActivePduData;
                }
                else if (pdu.GetType() == typeof(Client_Confirm_Active_Pdu))
                {
                    comfirmActivePdu = ((Client_Confirm_Active_Pdu)pdu.Clone()).confirmActivePduData;
                    if (channelManager == null)
                    {
                        channelManager = new ClientStaticVirtualChannelManager(this);
                    }
                }
                else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Pdu))
                {
                    lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Pdu)
                        pdu).disconnectProvider.reason.Value;
                }
                else if (pdu.GetType() == typeof(Server_Set_Error_Info_Pdu))
                {
                    lastErrorInfo = ((Server_Set_Error_Info_Pdu)pdu).errorInfoPduData.errorInfo;
                }
                else if (pdu.GetType() == typeof(Server_Status_Info_Pdu))
                {
                    lastStatusInfo = ((Server_Status_Info_Pdu)pdu).statusCode;
                }
                else if (pdu.GetType() == typeof(Server_Save_Session_Info_Pdu))
                {
                    Server_Save_Session_Info_Pdu saveSessionInfoPdu = (Server_Save_Session_Info_Pdu)pdu.Clone();

                    switch (saveSessionInfoPdu.saveSessionInfoPduData.infoType)
                    {
                        case infoType_Values.INFOTYPE_LOGON:
                            logonInfoV1 = (TS_LOGON_INFO)saveSessionInfoPdu.saveSessionInfoPduData.infoData;
                            break;

                        case infoType_Values.INFOTYPE_LOGON_LONG:
                            logonInfoV2 = (TS_LOGON_INFO_VERSION_2)saveSessionInfoPdu.saveSessionInfoPduData.infoData;
                            break;

                        case infoType_Values.INFOTYPE_LOGON_EXTENDED_INF:
                            TS_LOGON_INFO_EXTENDED infoExtended =
                                (TS_LOGON_INFO_EXTENDED)saveSessionInfoPdu.saveSessionInfoPduData.infoData;
                            switch (infoExtended.FieldsPresent)
                            {
                                case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE
                                   | FieldsPresent_Values.LOGON_EX_LOGONERRORS:
                                    autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData;
                                    logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[1].FieldData;
                                    break;

                                case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE:
                                    autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData;
                                    break;

                                case FieldsPresent_Values.LOGON_EX_LOGONERRORS:
                                    logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[0].FieldData;
                                    break;

                                default:
                                    break;
                            }
                            break;

                        default:
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// [TD Reference 3.2.5.3.4]
        /// Decode MCS Connect Response PDU with GCC Conference Create Response
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <returns>decoded MCS Connect Response PDU with GCC Conference Create Response PDU</returns>
        public StackPacket DecodeMcsConnectResponsePDU(byte[] data)
        {
            // initialize
            int currentIndex = 0;
            Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response pdu =
                new Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response();

            // McsConnectResponse: TpktHeader
            pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex);

            // McsConnectResponse: X224
            pdu.x224Data = ParseX224Data(data, ref currentIndex);

            // T125 Data: decode McsConnectResponse
            int t125DataLength = data.Length - currentIndex;
            if (t125DataLength <= 0)
            {
                throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE);
            }
            byte[] t125Data = new byte[t125DataLength];
            Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length);
            Connect_Response mcsConnectResponse = new Connect_Response();
            Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data);
            mcsConnectResponse.BerDecode(decodeBuffer);

            // McsConnectResponse:result
            pdu.mcsCrsp.result = (int)mcsConnectResponse.result.Value;
            byte[] userData = mcsConnectResponse.userData.ByteArrayValue;

            // T125 Data: decode McsConnectResponse's user data
            Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData);
            ConnectData connectData = new ConnectData();
            connectData.PerDecode(connectDataBuffer);

            // T125 Data: get Gcc data
            int gccDataLength = userData.Length - ConstValue.GCC_DATA_OFFSET;
            if (gccDataLength <= 0)
            {
                throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE);
            }
            byte[] gccData = new byte[gccDataLength];
            Array.Copy(userData, ConstValue.GCC_DATA_OFFSET, gccData, 0, gccData.Length);

            // T125 Data: decode Gcc user data
            ConnectGCCPDU gccPdu = new ConnectGCCPDU();
            Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData);
            gccPdu.PerDecode(gccPduBuffer);

            // McsConnectResponse: H221Key
            ConferenceCreateResponse conferenceResponse = (ConferenceCreateResponse)gccPdu.GetData();
            H221NonStandardIdentifier identifier =
                (H221NonStandardIdentifier)conferenceResponse.userData.Elements[0].key.GetData();
            pdu.mcsCrsp.gccPdu.H221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue);

            // McsConnectResponse: ccrResult
            pdu.mcsCrsp.gccPdu.ccrResult = (int)conferenceResponse.result.Value;

            // McsConnectResponse: nodeID
            pdu.mcsCrsp.gccPdu.nodeID = (int)conferenceResponse.nodeID.Value;

            // McsConnectResponse: tag
            pdu.mcsCrsp.gccPdu.tag = (int)conferenceResponse.tag.Value;

            // T125 Data: get Gcc user data
            byte[] gccUserData = conferenceResponse.userData.Elements[0].value.ByteArrayValue;

            // Reset current index
            currentIndex = 0;
            while (currentIndex < gccUserData.Length)
            {
                // Peek data type
                int tempIndex = currentIndex;
                TS_UD_HEADER_type_Values type =
                    (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false);

                // Parse data by type
                switch (type)
                {
                    case TS_UD_HEADER_type_Values.SC_CORE:
                        pdu.mcsCrsp.gccPdu.serverCoreData = ParseTsUdScCore(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_NET:
                        pdu.mcsCrsp.gccPdu.serverNetworkData = ParseTsUdScNet(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_SECURITY:
                        pdu.mcsCrsp.gccPdu.serverSecurityData = ParseTsUdScSec1(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_MCS_MSGCHANNEL:
                        pdu.mcsCrsp.gccPdu.serverMessageChannelData = ParseTsUdScMSGChannel(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_MULTITRANSPORT:
                        pdu.mcsCrsp.gccPdu.serverMultitransportChannelData = ParseTsUdScMultiTransport(gccUserData, ref currentIndex);
                        break;

                    default:
                        throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED);
                }
            }

            // Check if data length exceeded expectation
            VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED);
            return pdu;
        }
예제 #5
0
        /// <summary>
        /// Create an instance of the class that is identical to the current PDU. 
        /// </summary>
        /// <returns>The new instance.</returns>
        public override StackPacket Clone()
        {
            Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response cloneMCSRspPdu =
                new Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response(serverSessionContext);

            cloneMCSRspPdu.tpktHeader = tpktHeader;
            cloneMCSRspPdu.x224Data = x224Data;

            if (mcsCrsp != null)
            {
                cloneMCSRspPdu.mcsCrsp = new MCSConnectResponse();
                cloneMCSRspPdu.mcsCrsp.gccPdu = null;
                cloneMCSRspPdu.mcsCrsp.result = mcsCrsp.result;
                //cloneMCSRspPdu.mcsCrsp.calledConnectId = mcsCrsp.calledConnectId;
                //cloneMCSRspPdu.mcsCrsp.domainParameters = mcsCrsp.domainParameters;

                if (mcsCrsp.gccPdu != null)
                {
                    cloneMCSRspPdu.mcsCrsp.gccPdu = new ConnectGCCRsp();
                    cloneMCSRspPdu.mcsCrsp.gccPdu.serverCoreData = null;
                    cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData = null;
                    cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData = null;
                    cloneMCSRspPdu.mcsCrsp.gccPdu.nodeID = mcsCrsp.gccPdu.nodeID;
                    cloneMCSRspPdu.mcsCrsp.gccPdu.tag = mcsCrsp.gccPdu.tag;
                    cloneMCSRspPdu.mcsCrsp.gccPdu.ccrResult = mcsCrsp.gccPdu.ccrResult;
                    cloneMCSRspPdu.mcsCrsp.gccPdu.H221Key = mcsCrsp.gccPdu.H221Key;

                    if (mcsCrsp.gccPdu.serverCoreData != null)
                    {
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverCoreData = new TS_UD_SC_CORE();
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverCoreData.header =
                            mcsCrsp.gccPdu.serverCoreData.header;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverCoreData.version =
                            mcsCrsp.gccPdu.serverCoreData.version;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverCoreData.clientRequestedProtocols =
                            mcsCrsp.gccPdu.serverCoreData.clientRequestedProtocols;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverCoreData.earlyCapabilityFlags =
                            mcsCrsp.gccPdu.serverCoreData.earlyCapabilityFlags;
                    }
                    if (mcsCrsp.gccPdu.serverNetworkData != null)
                    {
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData = new TS_UD_SC_NET();
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData.header =
                            mcsCrsp.gccPdu.serverNetworkData.header;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData.MCSChannelId =
                            mcsCrsp.gccPdu.serverNetworkData.MCSChannelId;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData.channelCount =
                            mcsCrsp.gccPdu.serverNetworkData.channelCount;
                        if (mcsCrsp.gccPdu.serverNetworkData.channelIdArray != null)
                        {
                            cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData.channelIdArray =
                                new ushort[mcsCrsp.gccPdu.serverNetworkData.channelIdArray.Length];
                            mcsCrsp.gccPdu.serverNetworkData.channelIdArray.CopyTo(
                                cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData.channelIdArray,
                                0);
                        }
                        if (mcsCrsp.gccPdu.serverNetworkData.Pad != null)
                        {
                            cloneMCSRspPdu.mcsCrsp.gccPdu.serverNetworkData.Pad =
                                RdpbcgrUtility.CloneByteArray(mcsCrsp.gccPdu.serverNetworkData.Pad);
                        }
                    }
                    if (mcsCrsp.gccPdu.serverSecurityData != null)
                    {
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData = new TS_UD_SC_SEC1();
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.header =
                            mcsCrsp.gccPdu.serverSecurityData.header;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.encryptionLevel =
                            mcsCrsp.gccPdu.serverSecurityData.encryptionLevel;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.encryptionMethod =
                            mcsCrsp.gccPdu.serverSecurityData.encryptionMethod;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverRandomLen =
                            mcsCrsp.gccPdu.serverSecurityData.serverRandomLen;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverCertLen =
                            mcsCrsp.gccPdu.serverSecurityData.serverCertLen;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverRandom =
                            RdpbcgrUtility.CloneByteArray(mcsCrsp.gccPdu.serverSecurityData.serverRandom);
                        //////not implemented yet!

                        if (mcsCrsp.gccPdu.serverSecurityData.serverCertificate != null)
                        {
                            cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverCertificate = new SERVER_CERTIFICATE();
                            cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverCertificate.dwVersion =
                                mcsCrsp.gccPdu.serverSecurityData.serverCertificate.dwVersion;

                            if (mcsCrsp.gccPdu.serverSecurityData.serverCertificate.dwVersion ==
                                SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_1)
                            {
                                PROPRIETARYSERVERCERTIFICATE cert = (PROPRIETARYSERVERCERTIFICATE)
                                    mcsCrsp.gccPdu.serverSecurityData.serverCertificate.certData;
                                cert.SignatureBlob = RdpbcgrUtility.CloneByteArray(cert.SignatureBlob);
                                cert.PublicKeyBlob.modulus = RdpbcgrUtility.CloneByteArray(cert.PublicKeyBlob.modulus);
                                cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverCertificate.certData = cert;
                            }
                            else
                            {
                                X509_CERTIFICATE_CHAIN x509cert = (X509_CERTIFICATE_CHAIN)mcsCrsp.gccPdu.serverSecurityData.serverCertificate.certData;
                                for(int i = 0; i < x509cert.CertBlobArray.Length; i++)
                                {
                                    x509cert.CertBlobArray[i].abCert = RdpbcgrUtility.CloneByteArray(x509cert.CertBlobArray[i].abCert);
                                }
                                x509cert.Padding = RdpbcgrUtility.CloneByteArray(x509cert.Padding);
                                cloneMCSRspPdu.mcsCrsp.gccPdu.serverSecurityData.serverCertificate.certData = x509cert;
                            }
                        }
                    }
                    if (mcsCrsp.gccPdu.serverMessageChannelData != null)
                    {
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverMessageChannelData = new TS_UD_SC_MCS_MSGCHANNEL();
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverMessageChannelData.header = mcsCrsp.gccPdu.serverMessageChannelData.header;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverMessageChannelData.MCSChannelID = mcsCrsp.gccPdu.serverMessageChannelData.MCSChannelID;
                    }
                    if (mcsCrsp.gccPdu.serverMultitransportChannelData != null)
                    {
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverMultitransportChannelData = new TS_UD_SC_MULTITRANSPORT();
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverMultitransportChannelData.header = mcsCrsp.gccPdu.serverMultitransportChannelData.header;
                        cloneMCSRspPdu.mcsCrsp.gccPdu.serverMultitransportChannelData.flags = mcsCrsp.gccPdu.serverMultitransportChannelData.flags;
                    }
                }
            }
            return cloneMCSRspPdu;
        }
 public Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response_Ex(Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response orgPdu, RdpbcgrServerSessionContext serverSessionContext, NegativeType invalidType)
     : base(serverSessionContext)
 {
     this.tpktHeader = orgPdu.tpktHeader;
     this.x224Data = orgPdu.x224Data;
     this.mcsCrsp = orgPdu.mcsCrsp;
     this.invalidType = invalidType;
 }