/// <summary>
        /// Method to receive and decode client capabilities.
        /// </summary>
        /// <param name="serverMaxRequestSize">The MaxRequestSize field of the server-to-client Multifragment Update Capability Set. </param>
        /// <param name="supportedRfxCaps">Output the TS_RFX_ICAP array supported by the client.</param>
        public void ReceiveAndCheckClientCapabilities(uint serverMaxRequestSize, out TS_RFX_ICAP[] supportedRfxCaps)
        {
            supportedRfxCaps      = null;
            s2cMaxRequestSize     = serverMaxRequestSize;
            ConfirmCapabilitySets = this.rdpbcgrSessionContext.ConfirmCapabilitySets;
            foreach (ITsCapsSet capSet in ConfirmCapabilitySets)
            {
                if (capSet is TS_MULTIFRAGMENTUPDATE_CAPABILITYSET)
                {
                    this.is_Client_Multifragment_Update_CapabilitySet_Received = true;
                    this.client_Multifragment_Update_CapabilitySet             = (TS_MULTIFRAGMENTUPDATE_CAPABILITYSET)capSet;
                }
                else if (capSet is TS_LARGE_POINTER_CAPABILITYSET)
                {
                    this.is_Client_Large_Pointer_Capability_Set_Received = true;
                    this.client_Large_Pointer_Capability_Set             = (TS_LARGE_POINTER_CAPABILITYSET)capSet;
                }
                else if (capSet is TS_BITMAPCACHE_CAPABILITYSET_REV2)
                {
                    this.is_Client_Revision2_Bitmap_Cache_Capability_Set_Received = true;
                    this.client_Revision2_Bitmap_Cache_Capability_Set             = (TS_BITMAPCACHE_CAPABILITYSET_REV2)capSet;
                }
                else if (capSet is TS_FRAME_ACKNOWLEDGE_CAPABILITYSET)
                {
                    this.is_TS_FRAME_ACKNOWLEDGE_CAPABILITYSET_Received = true;
                    this.clientTS_FRAME_ACKNOWLEDGE_CAPABILITYSET       = (TS_FRAME_ACKNOWLEDGE_CAPABILITYSET)capSet;
                }
                else if (capSet is TS_SURFCMDS_CAPABILITYSET)
                {
                    this.is_Client_Surface_Commands_Capability_Set_Received = true;
                    this.client_Surface_Commands_Capability_Set             = (TS_SURFCMDS_CAPABILITYSET)capSet;
                    if ((this.client_Surface_Commands_Capability_Set.cmdFlags & CmdFlags_Values.SURFCMDS_STREAMSURFACEBITS) == CmdFlags_Values.SURFCMDS_STREAMSURFACEBITS)
                    {
                        this.clientupportStreamSurfaceBits = true;
                    }
                }
                else if (capSet is TS_BITMAPCODECS_CAPABILITYSET)
                {
                    this.is_Client_Bitmap_Codecs_Capability_Set_Received = true;
                    this.client_Bitmap_Codecs_Capability_Set             = (TS_BITMAPCODECS_CAPABILITYSET)capSet;
                    foreach (TS_BITMAPCODEC codec in this.client_Bitmap_Codecs_Capability_Set.supportedBitmapCodecs.bitmapCodecArray)
                    {
                        if (is_REMOTEFX_CODEC_GUID(codec.codecGUID))
                        {
                            is_TS_RFX_CLNT_CAPS_CONTAINER_Received = true;
                            remoteFXCodecID = codec.codecID;
                            this.client_RFX_Caps_Container = rdprfxServerDecoder.Decode_TS_RFX_CLNT_CAPS_CONTAINER(codec.codecProperties);
                            supportedRfxCaps = this.client_RFX_Caps_Container.capsData.capsetsData[0].icapsData;
                            break;
                        }
                    }
                }
            }

            //Verify Client Capabilities
            VerifyClientCapabilities();
        }
 //Get capability information from Client_Confirm_Active_Pdu,
 //will be added to ConfirmActiveRequest event
 private void testClassBase_getConfirmActivePduInfo(Client_Confirm_Active_Pdu confirmActivePdu)
 {
     foreach (ITsCapsSet cap in confirmActivePdu.confirmActivePduData.capabilitySets)
     {
         if (cap.GetCapabilityType() == capabilitySetType_Values.CAPSTYPE_BITMAPCACHE_REV2)
         {
             TS_BITMAPCACHE_CAPABILITYSET_REV2 bitmapCacheV2 = (TS_BITMAPCACHE_CAPABILITYSET_REV2)cap;
             if ((bitmapCacheV2.CacheFlags & CacheFlags_Values.PERSISTENT_KEYS_EXPECTED_FLAG) != 0)
             {
                 isclientSupportPersistentBitmapCache = true;
             }
         }
     }
 }
        /// <summary>
        /// Establish RDP Connection
        /// </summary>
        private void EstablishRDPConnection()
        {
            sessionContext = rdpbcgrServerStack.ExpectConnect(timeout);

            #region Connection Initial
            x224ConnectionRequest = ExpectPacket <Client_X_224_Connection_Request_Pdu>(sessionContext, timeout);
            Server_X_224_Connection_Confirm_Pdu confirmPdu
                = rdpbcgrServerStack.CreateX224ConnectionConfirmPdu(sessionContext, selectedProtocols_Values.PROTOCOL_RDP_FLAG, RDP_NEG_RSP_flags_Values.DYNVC_GFX_PROTOCOL_SUPPORTED | RDP_NEG_RSP_flags_Values.EXTENDED_CLIENT_DATA_SUPPORTED);

            SendPdu(confirmPdu);

            if (bool.Parse(detectInfo.IsWindowsImplementation))
            {
                RdpbcgrServerSessionContext orgSession = sessionContext;
                sessionContext = rdpbcgrServerStack.ExpectConnect(timeout);
                if (sessionContext.Identity == orgSession.Identity)
                {
                    sessionContext = rdpbcgrServerStack.ExpectConnect(timeout);
                }
                x224ConnectionRequest = ExpectPacket <Client_X_224_Connection_Request_Pdu>(sessionContext, timeout);
                confirmPdu            = rdpbcgrServerStack.CreateX224ConnectionConfirmPdu(sessionContext, selectedProtocols_Values.PROTOCOL_RDP_FLAG, RDP_NEG_RSP_flags_Values.DYNVC_GFX_PROTOCOL_SUPPORTED | RDP_NEG_RSP_flags_Values.EXTENDED_CLIENT_DATA_SUPPORTED);

                SendPdu(confirmPdu);
            }
            #endregion Connection Initial

            #region Basic Setting Exchange

            mscConnectionInitialPDU = ExpectPacket <Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request>(sessionContext, timeout);

            SERVER_CERTIFICATE cert = null;
            int certLen             = 0;
            int dwKeysize           = 2048;

            byte[] privateExp, publicExp, modulus;
            cert    = rdpbcgrServerStack.GenerateCertificate(dwKeysize, out privateExp, out publicExp, out modulus);
            certLen = 120 + dwKeysize / 8;

            Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response connectRespPdu = rdpbcgrServerStack.CreateMCSConnectResponsePduWithGCCConferenceCreateResponsePdu(
                sessionContext,
                EncryptionMethods.ENCRYPTION_METHOD_128BIT,
                EncryptionLevel.ENCRYPTION_LEVEL_LOW,
                cert,
                certLen,
                MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDPFECL | MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDPFECR);
            SendPdu(connectRespPdu);

            sessionContext.ServerPrivateExponent = new byte[privateExp.Length];
            Array.Copy(privateExp, sessionContext.ServerPrivateExponent, privateExp.Length);

            #endregion Basic Setting Exchange

            #region Channel Connection

            ExpectPacket <Client_MCS_Erect_Domain_Request>(sessionContext, timeout);
            ExpectPacket <Client_MCS_Attach_User_Request>(sessionContext, timeout);

            Server_MCS_Attach_User_Confirm_Pdu attachUserConfirmPdu = rdpbcgrServerStack.CreateMCSAttachUserConfirmPdu(sessionContext);
            SendPdu(attachUserConfirmPdu);

            //Join Channel
            int channelNum = 2;
            if (sessionContext.VirtualChannelIdStore != null)
            {
                channelNum += sessionContext.VirtualChannelIdStore.Length;
            }
            if (sessionContext.IsServerMessageChannelDataSend)
            {
                channelNum++;
            }
            for (int i = 0; i < channelNum; i++)
            {
                Client_MCS_Channel_Join_Request     channelJoinPdu      = ExpectPacket <Client_MCS_Channel_Join_Request>(sessionContext, timeout);
                Server_MCS_Channel_Join_Confirm_Pdu channelJoinResponse = rdpbcgrServerStack.CreateMCSChannelJoinConfirmPdu(
                    sessionContext,
                    channelJoinPdu.mcsChannelId);
                SendPdu(channelJoinResponse);
            }
            #endregion Channel Connection

            #region RDP Security Commencement

            securityExchangePDU = ExpectPacket <Client_Security_Exchange_Pdu>(sessionContext, timeout);

            #endregion RDP Security Commencement

            #region Secure Setting Exchange
            clientInfoPDU = ExpectPacket <Client_Info_Pdu>(sessionContext, timeout);
            #endregion Secure Setting Exchange

            #region Licensing
            Server_License_Error_Pdu_Valid_Client licensePdu = rdpbcgrServerStack.CreateLicenseErrorMessage(sessionContext);
            SendPdu(licensePdu);
            #endregion Licensing

            #region Capabilities Exchange

            RdpbcgrCapSet capSet = new RdpbcgrCapSet();
            capSet.GenerateCapabilitySets();
            Server_Demand_Active_Pdu demandActivePdu = rdpbcgrServerStack.CreateDemandActivePdu(sessionContext, capSet.CapabilitySets);
            SendPdu(demandActivePdu);

            confirmActivePDU            = ExpectPacket <Client_Confirm_Active_Pdu>(sessionContext, timeout);
            clientCapSet                = new RdpbcgrCapSet();
            clientCapSet.CapabilitySets = confirmActivePDU.confirmActivePduData.capabilitySets;
            #endregion Capabilities Exchange

            #region Connection Finalization
            ExpectPacket <Client_Synchronize_Pdu>(sessionContext, timeout);

            Server_Synchronize_Pdu synchronizePdu = rdpbcgrServerStack.CreateSynchronizePdu(sessionContext);
            SendPdu(synchronizePdu);

            Server_Control_Pdu controlCooperatePdu = rdpbcgrServerStack.CreateControlCooperatePdu(sessionContext);
            SendPdu(controlCooperatePdu);

            ExpectPacket <Client_Control_Pdu_Cooperate>(sessionContext, timeout);

            ExpectPacket <Client_Control_Pdu_Request_Control>(sessionContext, timeout);

            Server_Control_Pdu controlGrantedPdu = rdpbcgrServerStack.CreateControlGrantedPdu(sessionContext);
            SendPdu(controlGrantedPdu);


            ITsCapsSet cap = this.clientCapSet.FindCapSet(capabilitySetType_Values.CAPSTYPE_BITMAPCACHE_REV2);
            if (cap != null)
            {
                TS_BITMAPCACHE_CAPABILITYSET_REV2 bitmapCacheV2 = (TS_BITMAPCACHE_CAPABILITYSET_REV2)cap;
                if ((bitmapCacheV2.CacheFlags & CacheFlags_Values.PERSISTENT_KEYS_EXPECTED_FLAG) != 0)
                {
                    ExpectPacket <Client_Persistent_Key_List_Pdu>(sessionContext, timeout);
                }
            }

            ExpectPacket <Client_Font_List_Pdu>(sessionContext, timeout);

            Server_Font_Map_Pdu fontMapPdu = rdpbcgrServerStack.CreateFontMapPdu(sessionContext);
            SendPdu(fontMapPdu);

            #endregion Connection Finalization

            // Init for RDPEDYC
            try
            {
                rdpedycServer = new RdpedycServer(rdpbcgrServerStack, sessionContext);
                rdpedycServer.ExchangeCapabilities(timeout);
            }
            catch (Exception)
            {
                rdpedycServer = null;
            }
        }
        /// <summary>
        ///  Expect a client initiated RDP connection sequence.
        /// </summary>
        /// <param name="serverSelectedProtocol">The server selected security protocol.</param>
        /// <param name="enMethod">The server selected security method.</param>
        /// <param name="enLevel">The server selected security level.</param>
        /// <param name="isExtendedClientDataSupported">Indicates if server supports Extended Client Data Blocks.</param>
        /// <param name="expectAutoReconnect">Indicates if expect an Auto-Connect sequence.</param>
        /// <param name="rdpServerVersion">The RDP Sever version</param>
        /// <param name="isMultitransportSupported">Whether support multitransport</param>
        /// <param name="supportRDPEGFX">Whether support RDPEGFX</param>
        /// <param name="supportRestrictedAdminMode">Whether support restricted admin mode</param>
        public void EstablishRDPConnection(
            selectedProtocols_Values serverSelectedProtocol,
            EncryptionMethods enMethod,
            EncryptionLevel enLevel,
            bool isExtendedClientDataSupported,
            bool expectAutoReconnect,
            TS_UD_SC_CORE_version_Values rdpServerVersion,
            bool isMultitransportSupported = false,
            bool supportRDPEGFX            = false, bool supportRestrictedAdminMode = false)
        {
            #region Logging
            this.site.Log.Add(LogEntryKind.Comment, @"EstablishRDPConnection(
                Selected Protocol = {0},
                Encyrption Method = {1},
                Encyrption Level = {2},
                Extended Client Data Supported = {3},
                Auto-Reconnection Expected = {4},
                RDP Version Code= {5}).",
                              serverSelectedProtocol.ToString(), enMethod.ToString(), enLevel.ToString(), isExtendedClientDataSupported, expectAutoReconnect, rdpServerVersion.ToString());
            #endregion

            //Update server config context.
            serverConfig.selectedProtocol = serverSelectedProtocol;
            serverConfig.encryptionMethod = enMethod;
            serverConfig.encryptionLevel  = enLevel;
            serverConfig.isExtendedClientDataSupported = isExtendedClientDataSupported;

            #region Connection Initiation
            //5.4.2.1   Negotiation-Based Approach
            //Once the External Security Protocol (section 5.4.5) handshake has successfully run to completion,
            //the RDP messages resume, continuing with the MCS Connect Initial PDU (section 2.2.1.3).
            //if (serverConfig.encryptedProtocol != EncryptedProtocol.NegotiationCredSsp)
            //{

            ExpectPacket <Client_X_224_Connection_Request_Pdu>(sessionContext, pduWaitTimeSpan);

            RDP_NEG_RSP_flags_Values RDP_NEG_RSP_flags = RDP_NEG_RSP_flags_Values.None;
            if (serverConfig.isExtendedClientDataSupported)
            {
                RDP_NEG_RSP_flags |= RDP_NEG_RSP_flags_Values.EXTENDED_CLIENT_DATA_SUPPORTED;
            }
            if (supportRDPEGFX)
            {
                RDP_NEG_RSP_flags |= RDP_NEG_RSP_flags_Values.DYNVC_GFX_PROTOCOL_SUPPORTED;
            }
            if (supportRestrictedAdminMode)
            {
                RDP_NEG_RSP_flags |= RDP_NEG_RSP_flags_Values.RESTRICTED_ADMIN_MODE_SUPPORTED;
            }
            Server_X_224_Connection_Confirm(serverConfig.selectedProtocol, RDP_NEG_RSP_flags);

            //}
            #endregion

            #region Basic Setting Exchange
            ExpectPacket <Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request>(sessionContext, pduWaitTimeSpan);

            Server_MCS_Connect_Response(enMethod, enLevel, rdpServerVersion, NegativeType.None, isMultitransportSupported);
            #endregion

            #region Channel Connection
            ExpectPacket <Client_MCS_Erect_Domain_Request>(sessionContext, pduWaitTimeSpan);

            ExpectPacket <Client_MCS_Attach_User_Request>(sessionContext, pduWaitTimeSpan);

            MCSAttachUserConfirm(NegativeType.None);

            //Join Channel
            int channelNum = 2;
            if (sessionContext.VirtualChannelIdStore != null)
            {
                channelNum += sessionContext.VirtualChannelIdStore.Length;
            }
            if (sessionContext.IsServerMessageChannelDataSend)
            {
                channelNum++;
            }
            for (int i = 0; i < channelNum; i++)
            {
                ExpectPacket <Client_MCS_Channel_Join_Request>(sessionContext, pduWaitTimeSpan);
                MCSChannelJoinConfirm(lastRequestJoinChannelId, NegativeType.None);
            }
            #endregion

            #region RDP Security Commencement
            if (serverConfig.encryptedProtocol == EncryptedProtocol.Rdp)
            {
                ExpectPacket <Client_Security_Exchange_Pdu>(sessionContext, pduWaitTimeSpan);
            }
            #endregion

            #region Secure Setting Exchange
            ExpectPacket <Client_Info_Pdu>(sessionContext, pduWaitTimeSpan);
            if (expectAutoReconnect)
            {
                site.Assert.IsNotNull(tsInfoPacket.extraInfo, "TS_EXTENDED_INFO_PACKET should be provided in Auto-Reconnect sequence.");
                site.Assert.AreNotEqual <ushort>(0, tsInfoPacket.extraInfo.cbAutoReconnectLen, "The autoReconnectCookie should be provided in Auto-Reconnect sequence.");
            }
            #endregion

            #region Licensing
            Server_License_Error_Pdu_Valid_Client(NegativeType.None);
            #endregion

            #region Capabilities Exchange
            Server_Demand_Active(NegativeType.None);

            //Once the Confirm Active PDU has been sent, the client can start sending input PDUs (see section 2.2.8) to the server.
            ExpectPacket <Client_Confirm_Active_Pdu>(sessionContext, pduWaitTimeSpan);
            #endregion

            #region Connection Finalization
            WaitForPacket <Client_Synchronize_Pdu>(sessionContext, pduWaitTimeSpan);

            ServerSynchronize();

            ServerControlCooperate();

            WaitForPacket <Client_Control_Pdu_Cooperate>(sessionContext, pduWaitTimeSpan);

            WaitForPacket <Client_Control_Pdu_Request_Control>(sessionContext, pduWaitTimeSpan);

            ServerControlGrantedControl();

            if (serverConfig.CapabilitySetting.BitmapCacheHostSupportCapabilitySet)
            {
                ITsCapsSet cap = this.clientCapSet.FindCapSet(capabilitySetType_Values.CAPSTYPE_BITMAPCACHE_REV2);
                if (cap != null)
                {
                    TS_BITMAPCACHE_CAPABILITYSET_REV2 bitmapCacheV2 = (TS_BITMAPCACHE_CAPABILITYSET_REV2)cap;
                    if ((bitmapCacheV2.CacheFlags & CacheFlags_Values.PERSISTENT_KEYS_EXPECTED_FLAG) != 0)
                    {
                        WaitForPacket <Client_Persistent_Key_List_Pdu>(sessionContext, pduWaitTimeSpan);
                    }
                }
            }

            WaitForPacket <Client_Font_List_Pdu>(sessionContext, pduWaitTimeSpan);

            ServerFontMap();
            #endregion
        }
Example #5
0
        /// <summary>
        /// Creates a collection which contains all mandatory and optional capability sets
        /// </summary>
        /// <returns>collection fo Capability sets.</returns>
        public Collection <ITsCapsSet> CreateCapabilitySets(
            bool supportAutoReconnect,
            bool supportFastPathInput,
            bool supportFastPathOutput,
            bool supportSurfaceCommands,
            bool supportSVCCompression,
            bool supportRemoteFXCodec)
        {
            Collection <ITsCapsSet> capabilitySets = new Collection <ITsCapsSet>();

            #region Mandatory Capability Sets

            #region Populating general Capability Set, set auto-reconnect and fast-path output support
            TS_GENERAL_CAPABILITYSET generalCapabilitySet = new TS_GENERAL_CAPABILITYSET();
            generalCapabilitySet.capabilitySetType       = capabilitySetType_Values.CAPSTYPE_GENERAL;
            generalCapabilitySet.lengthCapability        = (ushort)Marshal.SizeOf(generalCapabilitySet);
            generalCapabilitySet.osMajorType             = osMajorType_Values.OSMAJORTYPE_WINDOWS;
            generalCapabilitySet.osMinorType             = osMinorType_Values.OSMINORTYPE_WINDOWS_NT;
            generalCapabilitySet.protocolVersion         = protocolVersion_Values.V1;
            generalCapabilitySet.pad2octetsA             = 0;
            generalCapabilitySet.generalCompressionTypes = generalCompressionTypes_Values.V1;
            generalCapabilitySet.extraFlags = extraFlags_Values.NO_BITMAP_COMPRESSION_HDR
                                              | extraFlags_Values.ENC_SALTED_CHECKSUM
                                              | extraFlags_Values.LONG_CREDENTIALS_SUPPORTED;
            // Add more flags according to parameters.
            if (supportAutoReconnect)
            {
                generalCapabilitySet.extraFlags |= extraFlags_Values.AUTORECONNECT_SUPPORTED;
            }
            if (supportFastPathOutput)
            {
                generalCapabilitySet.extraFlags |= extraFlags_Values.FASTPATH_OUTPUT_SUPPORTED;
            }
            generalCapabilitySet.updateCapabilityFlag    = updateCapabilityFlag_Values.V1;
            generalCapabilitySet.remoteUnshareFlag       = remoteUnshareFlag_Values.V1;
            generalCapabilitySet.generalCompressionLevel = generalCompressionLevel_Values.V1;
            generalCapabilitySet.refreshRectSupport      = refreshRectSupport_Values.TRUE;
            generalCapabilitySet.suppressOutputSupport   = suppressOutputSupport_Values.TRUE;
            generalCapabilitySet.lengthCapability        = (ushort)Marshal.SizeOf(generalCapabilitySet);

            capabilitySets.Add(generalCapabilitySet);
            #endregion  Populating general Capability Set

            #region Populating Bitmap Capability Set
            TS_BITMAP_CAPABILITYSET bitmapCapabilitySet = new TS_BITMAP_CAPABILITYSET();
            bitmapCapabilitySet.capabilitySetType     = capabilitySetType_Values.CAPSTYPE_BITMAP;
            bitmapCapabilitySet.lengthCapability      = (ushort)Marshal.SizeOf(bitmapCapabilitySet);
            bitmapCapabilitySet.preferredBitsPerPixel = RdpConstValue.BITMAP_CAP_BITS_PER_PIXEL_DEFAULT;
            bitmapCapabilitySet.receive1BitPerPixel   = RdpConstValue.BITMAP_CAP_SUPPORT_FEATURE;
            bitmapCapabilitySet.receive4BitsPerPixel  = RdpConstValue.BITMAP_CAP_SUPPORT_FEATURE;
            bitmapCapabilitySet.receive8BitsPerPixel  = RdpConstValue.BITMAP_CAP_SUPPORT_FEATURE;
            bitmapCapabilitySet.desktopWidth          = RdpConstValue.DESKTOP_WIDTH_DEFAULT;
            bitmapCapabilitySet.desktopHeight         = RdpConstValue.DESKTOP_HEIGHT_DEFAULT;
            bitmapCapabilitySet.pad2octets            = 0;
            bitmapCapabilitySet.desktopResizeFlag     = desktopResizeFlag_Values.TRUE;
            bitmapCapabilitySet.bitmapCompressionFlag = RdpConstValue.BITMAP_CAP_SUPPORT_FEATURE;
            bitmapCapabilitySet.highColorFlags        = 0;
            bitmapCapabilitySet.drawingFlags          = drawingFlags_Values.DRAW_ALLOW_COLOR_SUBSAMPLING
                                                        | drawingFlags_Values.DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY
                                                        | drawingFlags_Values.DRAW_ALLOW_SKIP_ALPHA
                                                        | drawingFlags_Values.DRAW_UNUSED_FLAG;
            bitmapCapabilitySet.multipleRectangleSupport = RdpConstValue.BITMAP_CAP_SUPPORT_FEATURE;
            bitmapCapabilitySet.pad2octetsB = 0;

            capabilitySets.Add(bitmapCapabilitySet);
            #endregion Populating Bitmap Capability Set

            #region Populating Order Capability Set
            TS_ORDER_CAPABILITYSET orderCapabilitySet = new TS_ORDER_CAPABILITYSET();
            orderCapabilitySet.capabilitySetType       = capabilitySetType_Values.CAPSTYPE_ORDER;
            orderCapabilitySet.terminalDescriptor      = new byte[RdpConstValue.ORDER_CAP_TERMINAL_DESCRIPTOR];
            orderCapabilitySet.pad4octetsA             = 0;
            orderCapabilitySet.desktopSaveXGranularity = RdpConstValue.ORDER_CAP_DESKTOP_X;
            orderCapabilitySet.desktopSaveYGranularity = RdpConstValue.ORDER_CAP_DESKTOP_Y;
            orderCapabilitySet.pad2octetsA             = 0;
            orderCapabilitySet.maximumOrderLevel       = RdpConstValue.ORD_LEVEL_1_ORDERS;
            orderCapabilitySet.numberFonts             = 0;
            orderCapabilitySet.orderFlags = orderFlags_Values.COLORINDEXSUPPORT
                                            | orderFlags_Values.ZEROBOUNDSDELTASSUPPORT
                                            | orderFlags_Values.NEGOTIATEORDERSUPPORT
                                            | orderFlags_Values.ORDERFLAGS_EXTRA_FLAGS; // If not set ORDERFLAGS_EXTRA_FLAGS flag when EGFX not supported, will get Server Set Error Info PDU with ErrInfoGraphicSubsystemFailed(4399)
            orderCapabilitySet.orderSupport        = RdpConstValue.ORDER_CAP_ORDER_SUPPORT_DEFAULT;
            orderCapabilitySet.textFlags           = 0;
            orderCapabilitySet.orderSupportExFlags =
                orderSupportExFlags_values.ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT | orderSupportExFlags_values.ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT;
            orderCapabilitySet.pad4octetsB      = 0;
            orderCapabilitySet.desktopSaveSize  = RdpConstValue.ORDER_CAP_DESKTOP_SIZE_DEFAULT;
            orderCapabilitySet.pad2octetsC      = 0;
            orderCapabilitySet.pad2octetsD      = 0;
            orderCapabilitySet.textANSICodePage = 0;
            orderCapabilitySet.pad2octetsE      = 0;
            orderCapabilitySet.lengthCapability = (ushort)(sizeof(ushort) * RdpConstValue.ORDER_CAP_USHORT_COUNT
                                                           + sizeof(uint) * RdpConstValue.ORDER_CAP_UINT_COUNT
                                                           + orderCapabilitySet.terminalDescriptor.Length
                                                           + orderCapabilitySet.orderSupport.Length);

            capabilitySets.Add(orderCapabilitySet);
            #endregion Populating Order Capability Set

            #region Populating BitmapCache Capability Set
            TS_BITMAPCACHE_CAPABILITYSET_REV2 bitmapCacheCapabilitySet = new TS_BITMAPCACHE_CAPABILITYSET_REV2();
            bitmapCacheCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_BITMAPCACHE_REV2;
            bitmapCacheCapabilitySet.CacheFlags        = CacheFlags_Values.ALLOW_CACHE_WAITING_LIST_FLAG
                                                         | CacheFlags_Values.PERSISTENT_KEYS_EXPECTED_FLAG;
            bitmapCacheCapabilitySet.pad2          = 0;
            bitmapCacheCapabilitySet.NumCellCaches = RdpConstValue.BITMAP_CACHE_NUM_CELL_DEFAULT;
            bitmapCacheCapabilitySet.BitmapCache1CellInfo.NumEntriesAndK = RdpConstValue.BITMAP_CACHE_CELL1_VALUE;
            bitmapCacheCapabilitySet.BitmapCache2CellInfo.NumEntriesAndK = RdpConstValue.BITMAP_CACHE_CELL2_VALUE;
            bitmapCacheCapabilitySet.BitmapCache3CellInfo.NumEntriesAndK = RdpConstValue.BITMAP_CACHE_CELL3_VALUE;
            bitmapCacheCapabilitySet.BitmapCache4CellInfo.NumEntriesAndK = 0;
            bitmapCacheCapabilitySet.BitmapCache5CellInfo.NumEntriesAndK = 0;
            bitmapCacheCapabilitySet.Pad3             = RdpConstValue.BITMAP_CACHE_PAD3;
            bitmapCacheCapabilitySet.lengthCapability = (ushort)(Marshal.SizeOf(bitmapCacheCapabilitySet)
                                                                 + bitmapCacheCapabilitySet.Pad3.Length
                                                                 - sizeof(int));

            capabilitySets.Add(bitmapCacheCapabilitySet);
            #endregion Populating BitmapCache Capability Set

            #region Populating Pointer Capability Set
            TS_POINTER_CAPABILITYSET pointerCapabilitySet = new TS_POINTER_CAPABILITYSET();
            pointerCapabilitySet.capabilitySetType     = capabilitySetType_Values.CAPSTYPE_POINTER;
            pointerCapabilitySet.colorPointerFlag      = colorPointerFlag_Values.TRUE;
            pointerCapabilitySet.colorPointerCacheSize = RdpConstValue.POINTER_CAP_COLOR_SIZE_DEFAULT;
            pointerCapabilitySet.pointerCacheSize      = RdpConstValue.POINTER_CAP_POINTER_SIZE_DEFAULT;
            pointerCapabilitySet.lengthCapability      = (ushort)Marshal.SizeOf(pointerCapabilitySet);

            capabilitySets.Add(pointerCapabilitySet);
            #endregion Populating Pointer Capability Set

            #region Populating Input Capability Set, set fast-path input support
            TS_INPUT_CAPABILITYSET inputCapabilitySet = new TS_INPUT_CAPABILITYSET();
            inputCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_INPUT;
            inputCapabilitySet.inputFlags        = inputFlags_Values.INPUT_FLAG_UNICODE
                                                   | inputFlags_Values.INPUT_FLAG_MOUSEX
                                                   | inputFlags_Values.INPUT_FLAG_SCANCODES;
            if (supportFastPathInput)
            {
                inputCapabilitySet.inputFlags |= inputFlags_Values.INPUT_FLAG_FASTPATH_INPUT2;
            }
            inputCapabilitySet.pad2octetsA         = 0;
            inputCapabilitySet.keyboardLayout      = RdpConstValue.LOCALE_ENGLISH_UNITED_STATES;
            inputCapabilitySet.keyboardType        = TS_INPUT_CAPABILITYSET_keyboardType_Values.V4;
            inputCapabilitySet.keyboardSubType     = 0;
            inputCapabilitySet.keyboardFunctionKey = RdpConstValue.KEYBOARD_FUNCTION_KEY_NUMBER_DEFAULT;
            inputCapabilitySet.imeFileName         = string.Empty;
            inputCapabilitySet.lengthCapability    = (ushort)(Marshal.SizeOf(inputCapabilitySet)
                                                              - sizeof(int)
                                                              + RdpConstValue.INPUT_CAP_IME_FLIENAME_SIZE);

            capabilitySets.Add(inputCapabilitySet);
            #endregion Populating Input Capability Set

            #region Populating Brush Capability Set
            TS_BRUSH_CAPABILITYSET brushCapabilitySet = new TS_BRUSH_CAPABILITYSET();
            brushCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_BRUSH;
            brushCapabilitySet.brushSupportLevel = brushSupportLevel_Values.BRUSH_COLOR_8x8;
            brushCapabilitySet.lengthCapability  = (ushort)Marshal.SizeOf(brushCapabilitySet);

            capabilitySets.Add(brushCapabilitySet);
            #endregion Populating Brush Capability Set

            #region Populating Glyph Cache Capability Set
            TS_GLYPHCACHE_CAPABILITYSET glyphCacheCapabilitySet = new TS_GLYPHCACHE_CAPABILITYSET();
            glyphCacheCapabilitySet.capabilitySetType                  = capabilitySetType_Values.CAPSTYPE_GLYPHCACHE;
            glyphCacheCapabilitySet.GlyphCache                         = new TS_CACHE_DEFINITION[RdpConstValue.CLYPH_CACHE_CAP_CLYPH_CACHE_NUM];
            glyphCacheCapabilitySet.GlyphCache[0].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[0].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_4;
            glyphCacheCapabilitySet.GlyphCache[1].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[1].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_8;
            glyphCacheCapabilitySet.GlyphCache[2].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[2].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_8;
            glyphCacheCapabilitySet.GlyphCache[3].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[3].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_4;
            glyphCacheCapabilitySet.GlyphCache[4].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[4].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_16;
            glyphCacheCapabilitySet.GlyphCache[5].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[5].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_32;
            glyphCacheCapabilitySet.GlyphCache[6].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[6].CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_64;
            glyphCacheCapabilitySet.GlyphCache[7].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[7].CacheMaximumCellSize =
                RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_128;
            glyphCacheCapabilitySet.GlyphCache[8].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_254;
            glyphCacheCapabilitySet.GlyphCache[8].CacheMaximumCellSize =
                RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_256;
            glyphCacheCapabilitySet.GlyphCache[9].CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_64;
            glyphCacheCapabilitySet.GlyphCache[9].CacheMaximumCellSize = 2048;

            glyphCacheCapabilitySet.FragCache = new TS_CACHE_DEFINITION();
            glyphCacheCapabilitySet.FragCache.CacheEntries         = RdpConstValue.CLYPH_CACHE_CAP_CACHE_ENTRY_NUM_256;
            glyphCacheCapabilitySet.FragCache.CacheMaximumCellSize = RdpConstValue.CLYPH_CACHE_CAP_CACHE_CELL_SIZE_256;
            glyphCacheCapabilitySet.GlyphSupportLevel = GlyphSupportLevel_Values.GLYPH_SUPPORT_ENCODE;
            glyphCacheCapabilitySet.pad2octets        = 0;
            glyphCacheCapabilitySet.lengthCapability  = (ushort)(sizeof(ushort)
                                                                 * RdpConstValue.CLYPH_CACHE_CAP_USHORT_COUNT);

            capabilitySets.Add(glyphCacheCapabilitySet);
            #endregion Populating Glyph Cache Capability Set

            #region Populating Offscreen Bitmap Cache Capability Set
            TS_OFFSCREEN_CAPABILITYSET offscreenCapabilitySet = new TS_OFFSCREEN_CAPABILITYSET();
            offscreenCapabilitySet.capabilitySetType     = capabilitySetType_Values.CAPSTYPE_OFFSCREENCACHE;
            offscreenCapabilitySet.offscreenSupportLevel = offscreenSupportLevel_Values.TRUE;
            offscreenCapabilitySet.offscreenCacheSize    = RdpConstValue.OFFSCREEN_CAP_MAX_CACHE_SIZE;
            offscreenCapabilitySet.offscreenCacheEntries = RdpConstValue.OFFSCREEN_CAP_CACHE_ENTRY_NUM;
            offscreenCapabilitySet.lengthCapability      = (ushort)Marshal.SizeOf(offscreenCapabilitySet);

            capabilitySets.Add(offscreenCapabilitySet);
            #endregion Populating Offscreen Bitmap Cache Capability Set

            #region Populating Virtual Channel Capability Set, set SVC compression support
            TS_VIRTUALCHANNEL_CAPABILITYSET virtualCapabilitySet = new TS_VIRTUALCHANNEL_CAPABILITYSET();
            virtualCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_VIRTUALCHANNEL;
            if (supportSVCCompression)
            {
                virtualCapabilitySet.flags = TS_VIRTUALCHANNEL_CAPABILITYSET_flags_Values.VCCAPS_COMPR_SC;
            }
            else
            {
                virtualCapabilitySet.flags = TS_VIRTUALCHANNEL_CAPABILITYSET_flags_Values.VCCAPS_NO_COMPR;
            }
            virtualCapabilitySet.lengthCapability = (ushort)Marshal.SizeOf(virtualCapabilitySet);
            virtualCapabilitySet.VCChunkSize      = 0;

            capabilitySets.Add(virtualCapabilitySet);
            #endregion Populating Virtual Channel Capability Set

            #region Populating Sound Capability Set
            TS_SOUND_CAPABILITYSET soundCapabilitySet = new TS_SOUND_CAPABILITYSET();
            soundCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_SOUND;
            soundCapabilitySet.soundFlags        = soundFlags_Values.SOUND_BEEPS_FLAG;
            soundCapabilitySet.pad2octetsA       = 0;
            soundCapabilitySet.lengthCapability  = (ushort)Marshal.SizeOf(soundCapabilitySet);

            capabilitySets.Add(soundCapabilitySet);
            #endregion Populating Sound Capability Set

            #endregion

            #region Optional Capability Sets

            #region Populating Bitmap Cache Host Support Capability Set
            TS_BITMAPCACHE_HOSTSUPPORT_CAPABILITYSET bitmapHostsupprot =
                new TS_BITMAPCACHE_HOSTSUPPORT_CAPABILITYSET();
            bitmapHostsupprot.capabilitySetType = capabilitySetType_Values.CAPSTYPE_BITMAPCACHE_HOSTSUPPORT;
            bitmapHostsupprot.cacheVersion      = cacheVersion_Values.V1;
            bitmapHostsupprot.pad1             = 0;
            bitmapHostsupprot.pad2             = 0;
            bitmapHostsupprot.lengthCapability = (ushort)Marshal.SizeOf(bitmapHostsupprot);

            capabilitySets.Add(bitmapHostsupprot);
            #endregion Populating Bitmap Cache Host Support Capability Set

            #region Populating Control Capability Set
            TS_CONTROL_CAPABILITYSET controlCapabilitySet = new TS_CONTROL_CAPABILITYSET();
            controlCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_CONTROL;
            controlCapabilitySet.controlFlags      = 0;
            controlCapabilitySet.remoteDetachFlag  = 0;
            controlCapabilitySet.controlInterest   = RdpConstValue.CONTROLPRIORITY_NEVER;
            controlCapabilitySet.detachInterest    = RdpConstValue.CONTROLPRIORITY_NEVER;
            controlCapabilitySet.lengthCapability  = (ushort)Marshal.SizeOf(controlCapabilitySet);

            capabilitySets.Add(controlCapabilitySet);
            #endregion Populating Control Capability Set


            #region Populating Windows Capability Set
            TS_WINDOWACTIVATION_CAPABILITYSET windowsCapabilitySet = new TS_WINDOWACTIVATION_CAPABILITYSET();
            windowsCapabilitySet.capabilitySetType    = capabilitySetType_Values.CAPSTYPE_ACTIVATION;
            windowsCapabilitySet.helpKeyFlag          = 0;
            windowsCapabilitySet.helpKeyIndexFlag     = 0;
            windowsCapabilitySet.helpExtendedKeyFlag  = 0;
            windowsCapabilitySet.windowManagerKeyFlag = 0;
            windowsCapabilitySet.lengthCapability     = (ushort)Marshal.SizeOf(windowsCapabilitySet);

            capabilitySets.Add(windowsCapabilitySet);
            #endregion Populating Windows Capability Set


            #region Populating Share Capability Set
            TS_SHARE_CAPABILITYSET shareCapabilitySet = new TS_SHARE_CAPABILITYSET();
            shareCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_SHARE;
            shareCapabilitySet.nodeId            = 0;
            shareCapabilitySet.pad2octets        = 0;
            shareCapabilitySet.lengthCapability  = (ushort)Marshal.SizeOf(shareCapabilitySet);

            capabilitySets.Add(shareCapabilitySet);
            #endregion Populating Share Capability Set

            #region Populating Font Capability Set
            TS_FONT_CAPABILITYSET fontCapabilitySet = new TS_FONT_CAPABILITYSET();
            fontCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSTYPE_FONT;
            fontCapabilitySet.fontSupportFlags  = RdpConstValue.FONTSUPPORT_FONTLIST;
            fontCapabilitySet.pad2octets        = 0;
            fontCapabilitySet.lengthCapability  = (ushort)Marshal.SizeOf(fontCapabilitySet);

            capabilitySets.Add(fontCapabilitySet);
            #endregion Populating Font Capability Set

            #region Populating Multifragment Update Capability Set
            TS_MULTIFRAGMENTUPDATE_CAPABILITYSET multiFragmentCapabilitySet =
                new TS_MULTIFRAGMENTUPDATE_CAPABILITYSET();
            multiFragmentCapabilitySet.capabilitySetType = capabilitySetType_Values.CAPSETTYPE_MULTIFRAGMENTUPDATE;
            multiFragmentCapabilitySet.MaxRequestSize    = RdpConstValue.MULTIFRAGMENT_CAP_MAX_REQUEST_SIZE;
            multiFragmentCapabilitySet.lengthCapability  = (ushort)Marshal.SizeOf(multiFragmentCapabilitySet);

            capabilitySets.Add(multiFragmentCapabilitySet);
            #endregion Populating Multifragment Update Capability Set

            #region Populating Large Pointer Capability Set
            TS_LARGE_POINTER_CAPABILITYSET largePointerCapabilitySet = new TS_LARGE_POINTER_CAPABILITYSET();
            largePointerCapabilitySet.capabilitySetType        = capabilitySetType_Values.CAPSETTYPE_LARGE_POINTER;
            largePointerCapabilitySet.largePointerSupportFlags =
                largePointerSupportFlags_Values.LARGE_POINTER_FLAG_96x96;
            largePointerCapabilitySet.lengthCapability = sizeof(ushort) + sizeof(ushort) + sizeof(ushort);

            capabilitySets.Add(largePointerCapabilitySet);
            #endregion Populating Large Pointer Capability Set

            #region Populating Desktop Composition Capability Set
            TS_COMPDESK_CAPABILITYSET desktopCapabilitySet = new TS_COMPDESK_CAPABILITYSET();
            desktopCapabilitySet.capabilitySetType    = capabilitySetType_Values.CAPSETTYPE_COMPDESK;
            desktopCapabilitySet.CompDeskSupportLevel = CompDeskSupportLevel_Values.COMPDESK_SUPPORTED;
            desktopCapabilitySet.lengthCapability     = sizeof(ushort) + sizeof(ushort) + sizeof(ushort);

            capabilitySets.Add(desktopCapabilitySet);
            #endregion Populating Desktop Composition Capability Set

            #region Surface Commands Capability Set, set surface commands support
            TS_SURFCMDS_CAPABILITYSET surfCmdsCapSet = new TS_SURFCMDS_CAPABILITYSET();
            surfCmdsCapSet.capabilitySetType = capabilitySetType_Values.CAPSETTYPE_SURFACE_COMMANDS;
            if (supportSurfaceCommands)
            {
                surfCmdsCapSet.cmdFlags = CmdFlags_Values.SURFCMDS_FRAMEMARKER | CmdFlags_Values.SURFCMDS_SETSURFACEBITS | CmdFlags_Values.SURFCMDS_STREAMSURFACEBITS;
            }
            else
            {
                surfCmdsCapSet.cmdFlags = CmdFlags_Values.None;
            }
            surfCmdsCapSet.lengthCapability = sizeof(ushort) + sizeof(ushort) + sizeof(uint) + sizeof(uint);

            capabilitySets.Add(surfCmdsCapSet);
            #endregion

            #region Bitmap Codecs Capability Set
            TS_BITMAPCODECS_CAPABILITYSET codecsCapSet = new TS_BITMAPCODECS_CAPABILITYSET();
            codecsCapSet.capabilitySetType     = capabilitySetType_Values.CAPSETTYPE_BITMAP_CODECS;
            codecsCapSet.supportedBitmapCodecs = new TS_BITMAPCODECS();
            if (supportRemoteFXCodec)
            {
                codecsCapSet.supportedBitmapCodecs.bitmapCodecCount    = 3;
                codecsCapSet.supportedBitmapCodecs.bitmapCodecArray    = new TS_BITMAPCODEC[3];
                codecsCapSet.supportedBitmapCodecs.bitmapCodecArray[0] = this.CreateTS_BITMAPCODEC_NSCodec();
                codecsCapSet.supportedBitmapCodecs.bitmapCodecArray[1] = this.CreateTS_BITMAPCODEC_RemoteFX();
                codecsCapSet.supportedBitmapCodecs.bitmapCodecArray[2] = this.CreateTS_BITMAPCODEC_Image_RemoteFX();
            }
            else
            {
                codecsCapSet.supportedBitmapCodecs.bitmapCodecCount    = 1;
                codecsCapSet.supportedBitmapCodecs.bitmapCodecArray    = new TS_BITMAPCODEC[1];
                codecsCapSet.supportedBitmapCodecs.bitmapCodecArray[0] = this.CreateTS_BITMAPCODEC_NSCodec();
            }
            codecsCapSet.lengthCapability = (ushort)(sizeof(ushort) + sizeof(ushort) + sizeof(byte));
            foreach (TS_BITMAPCODEC codec in codecsCapSet.supportedBitmapCodecs.bitmapCodecArray)
            {
                codecsCapSet.lengthCapability += (ushort)(19 + codec.codecPropertiesLength);
            }

            capabilitySets.Add(codecsCapSet);
            #endregion

            #region TS_FRAME_ACKNOWLEDGE_CAPABILITYSET
            TS_FRAME_ACKNOWLEDGE_CAPABILITYSET frameAckCapSet = new TS_FRAME_ACKNOWLEDGE_CAPABILITYSET();
            frameAckCapSet.capabilitySetType           = capabilitySetType_Values.CAPSETTYPE_FRAME_ACKNOWLEDGE;
            frameAckCapSet.lengthCapability            = 8;
            frameAckCapSet.maxUnacknowledgedFrameCount = 2;

            capabilitySets.Add(frameAckCapSet);
            #endregion

            #endregion

            return(capabilitySets);
        }