The TS_CONFIRM_ACTIVE_PDU structure is a standard T.128 Confirm Active PDU (see [T128] section 8.4.1).
file:///C:/ts_dev/TestSuites/MS-RDPBCGR/TestSuite/Src/TD/latest_XMLS_16may/RDPBCGR/ _rfc_ms-rdpbcgr2_1_1_13_2_1.xml
        /// <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>
        /// 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;
                }
            }
        }
コード例 #3
0
        /// <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;
                    }
                }
            }
        }
コード例 #4
0
 /// <summary>
 /// 2.2.1.13.2.1
 /// </summary>
 /// <param name="confirmActive"></param>
 public void VerifyStructure(TS_CONFIRM_ACTIVE_PDU confirmActive)
 {
     site.CaptureRequirementIfAreEqual<ShareControlHeaderType>(ShareControlHeaderType.PDUTYPE_CONFIRMACTIVEPDU, (ShareControlHeaderType)(confirmActive.shareControlHeader.pduType.typeAndVersionLow & 0x15), 708,
         @"In TS_CONFIRM_ACTIVE_PDU structure, the type subfield of the pduType field of the Share Control Header MUST be set to"
         + @" PDUTYPE_CONFIRMACTIVEPDU (3).");
     site.CaptureRequirementIfAreEqual<originatorId_Values>(originatorId_Values.V1, confirmActive.originatorId, 711,
         @"In TS_CONFIRM_ACTIVE_PDU structure, the originatorId MUST be set to the server channel ID (in Microsoft RDP server "
         + @"implementations, this value is always 0x03EA)");
     site.CaptureRequirementIfAreEqual<ushort>((ushort)confirmActive.sourceDescriptor.Length, confirmActive.lengthSourceDescriptor, 713,
         @"In TS_CONFIRM_ACTIVE_PDU structure, the lengthSourceDescriptor gives the size in bytes of the sourceDescriptor field.");
     site.CaptureRequirementIfAreEqual<ushort>(confirmActive.numberCapabilities, (ushort)confirmActive.capabilitySets.Count, 718,
         @"In TS_CONFIRM_ACTIVE_PDU structure, numberCapabilities gives the number of capability sets included "
         + @"in the Confirm Active PDU.");
 }
コード例 #5
0
        /// <summary>
        /// Parse TS_CONFIRM_ACTIVE_PDU
        /// (parser index is updated according to parsed length)
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <param name="currentIndex">current parser index</param>
        /// <returns>TS_CONFIRM_ACTIVE_PDU</returns>
        private TS_CONFIRM_ACTIVE_PDU ParseTsConfirmActivePdu(byte[] data, ref int currentIndex)
        {
            TS_CONFIRM_ACTIVE_PDU pdu = new TS_CONFIRM_ACTIVE_PDU();
            pdu.shareControlHeader = ParseTsShareControlHeader(data, ref currentIndex);
            pdu.shareId = ParseUInt32(data, ref currentIndex, false);
            pdu.originatorId = (originatorId_Values)ParseUInt16(data, ref currentIndex, false);
            pdu.lengthSourceDescriptor = ParseUInt16(data, ref currentIndex, false);
            pdu.lengthCombinedCapabilities = ParseUInt16(data, ref currentIndex, false);
            pdu.sourceDescriptor =
                GetBytes(data, ref currentIndex, pdu.lengthSourceDescriptor);
            pdu.numberCapabilities = ParseUInt16(data, ref currentIndex, false);
            pdu.pad2Octets = ParseUInt16(data, ref currentIndex, false);
            pdu.capabilitySets = new Collection<ITsCapsSet>();
            while (currentIndex < data.Length)
            {
                pdu.capabilitySets.Add(ParseTsCapsSet(data, ref currentIndex));
            }

            return pdu;
        }
コード例 #6
0
        /// <summary>
        /// Create an instance of the class that is identical to the current PDU. 
        /// </summary>
        /// <returns>The new instance.</returns>
        public TS_CONFIRM_ACTIVE_PDU Clone()
        {
            TS_CONFIRM_ACTIVE_PDU cloneConfirmActivePdu = new TS_CONFIRM_ACTIVE_PDU();

            cloneConfirmActivePdu.lengthCombinedCapabilities = lengthCombinedCapabilities;
            cloneConfirmActivePdu.lengthSourceDescriptor = lengthSourceDescriptor;
            cloneConfirmActivePdu.numberCapabilities = numberCapabilities;
            cloneConfirmActivePdu.originatorId = originatorId;
            cloneConfirmActivePdu.pad2Octets = pad2Octets;
            cloneConfirmActivePdu.shareControlHeader = shareControlHeader;
            cloneConfirmActivePdu.shareId = shareId;
            cloneConfirmActivePdu.sourceDescriptor = RdpbcgrUtility.CloneByteArray(sourceDescriptor);
            if (capabilitySets != null)
            {
                cloneConfirmActivePdu.capabilitySets = new Collection<ITsCapsSet>();
                for (int i = 0; i < capabilitySets.Count; ++i)
                {
                    cloneConfirmActivePdu.capabilitySets.Add(RdpbcgrUtility.CloneCapabilitySet(capabilitySets[i]));
                }
            }

            return cloneConfirmActivePdu;
        }
コード例 #7
0
        /// <summary>
        /// Encode confirmActivePduData field.
        /// </summary>
        /// <param name="confirmActivePduData">The data to be encoded.</param>
        /// <returns>The encoded data.</returns>
        private static byte[] EncodeConfirmData(TS_CONFIRM_ACTIVE_PDU confirmActivePduData)
        {
            List<byte> confirmBuffer = new List<byte>();

            if (confirmActivePduData != null)
            {
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, confirmActivePduData.shareControlHeader);
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, confirmActivePduData.shareId);
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, (ushort)confirmActivePduData.originatorId);
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, confirmActivePduData.lengthSourceDescriptor);
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, confirmActivePduData.lengthCombinedCapabilities);
                RdpbcgrEncoder.EncodeBytes(confirmBuffer, confirmActivePduData.sourceDescriptor);
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, confirmActivePduData.numberCapabilities);
                RdpbcgrEncoder.EncodeStructure(confirmBuffer, confirmActivePduData.pad2Octets);

                for (int i = 0; i < confirmActivePduData.numberCapabilities; ++i)
                {
                    ITsCapsSet capability = confirmActivePduData.capabilitySets[i];
                    RdpbcgrEncoder.EncodeBytes(confirmBuffer, capability.ToBytes());
                }
            }

            return confirmBuffer.ToArray();
        }