public TS_RFX_CLNT_CAPS_CONTAINER Decode_TS_RFX_CLNT_CAPS_CONTAINER(byte[] data)
        {
            int curIdx = 0;
            TS_RFX_CLNT_CAPS_CONTAINER clientRFXCaps = new TS_RFX_CLNT_CAPS_CONTAINER();

            clientRFXCaps.length       = ParseUInt32(data, ref curIdx, false);
            clientRFXCaps.captureFlags = ParseUInt32(data, ref curIdx, false);
            clientRFXCaps.capsLength   = ParseUInt32(data, ref curIdx, false);

            byte[]      capsData = GetBytes(data, ref curIdx, (int)clientRFXCaps.capsLength);
            TS_RFX_CAPS caps     = new TS_RFX_CAPS();

            curIdx          = 0;
            caps.blockType  = (blockType_Value)ParseUInt16(capsData, ref curIdx, false);
            caps.blockLen   = ParseUInt32(capsData, ref curIdx, false);
            caps.numCapsets = ParseUInt16(capsData, ref curIdx, false);

            List <TS_RFX_CAPSET> capSetList = new List <TS_RFX_CAPSET>();

            for (int i = 0; i < caps.numCapsets; i++)
            {
                TS_RFX_CAPSET capSet = new TS_RFX_CAPSET();
                capSet.blockType  = (blockType_Value)(blockType_Value)ParseUInt16(capsData, ref curIdx, false);
                capSet.blockLen   = ParseUInt32(capsData, ref curIdx, false);
                capSet.codecId    = ParseByte(capsData, ref curIdx);
                capSet.capsetType = ParseUInt16(capsData, ref curIdx, false);
                capSet.numIcaps   = ParseUInt16(capsData, ref curIdx, false);
                capSet.icapLen    = ParseUInt16(capsData, ref curIdx, false);

                List <TS_RFX_ICAP> icapList = new List <TS_RFX_ICAP>();
                for (int j = 0; j < capSet.numIcaps; j++)
                {
                    TS_RFX_ICAP icap = new TS_RFX_ICAP();
                    icap.version       = (version_Value)ParseUInt16(capsData, ref curIdx, false);
                    icap.tileSize      = (short)ParseUInt16(capsData, ref curIdx, false);
                    icap.flags         = ParseByte(capsData, ref curIdx);
                    icap.colConvBits   = ParseByte(capsData, ref curIdx);
                    icap.transformBits = ParseByte(capsData, ref curIdx);
                    icap.entropyBits   = (entropyBits_Value)ParseByte(capsData, ref curIdx);
                    icapList.Add(icap);
                }
                capSet.icapsData = icapList.ToArray();
                capSetList.Add(capSet);
            }
            caps.capsetsData       = capSetList.ToArray();
            clientRFXCaps.capsData = caps;
            return(clientRFXCaps);
        }
        public TS_RFX_CLNT_CAPS_CONTAINER Decode_TS_RFX_CLNT_CAPS_CONTAINER(byte[] data)
        {
            int curIdx = 0;
            TS_RFX_CLNT_CAPS_CONTAINER clientRFXCaps = new TS_RFX_CLNT_CAPS_CONTAINER();
            clientRFXCaps.length = ParseUInt32(data, ref curIdx, false);
            clientRFXCaps.captureFlags = ParseUInt32(data, ref curIdx, false);
            clientRFXCaps.capsLength = ParseUInt32(data, ref curIdx, false);

            byte[] capsData = GetBytes(data,ref curIdx,(int)clientRFXCaps.capsLength);
            TS_RFX_CAPS caps = new TS_RFX_CAPS();
            curIdx = 0;
            caps.blockType = (blockType_Value)ParseUInt16(capsData, ref curIdx, false);
            caps.blockLen = ParseUInt32(capsData, ref curIdx, false);
            caps.numCapsets = ParseUInt16(capsData, ref curIdx, false);

            List<TS_RFX_CAPSET> capSetList = new List<TS_RFX_CAPSET>();
            for (int i = 0; i < caps.numCapsets; i++)
            {
                TS_RFX_CAPSET capSet = new TS_RFX_CAPSET();
                capSet.blockType = (blockType_Value)(blockType_Value)ParseUInt16(capsData, ref curIdx, false);
                capSet.blockLen = ParseUInt32(capsData, ref curIdx, false);
                capSet.codecId = ParseByte(capsData, ref curIdx);
                capSet.capsetType = ParseUInt16(capsData, ref curIdx, false);
                capSet.numIcaps = ParseUInt16(capsData, ref curIdx, false);
                capSet.icapLen = ParseUInt16(capsData, ref curIdx, false);

                List<TS_RFX_ICAP> icapList = new List<TS_RFX_ICAP>();
                for (int j = 0; j < capSet.numIcaps; j++)
                {
                    TS_RFX_ICAP icap = new TS_RFX_ICAP();
                    icap.version = (version_Value)ParseUInt16(capsData, ref curIdx, false);
                    icap.tileSize = (short)ParseUInt16(capsData, ref curIdx, false);
                    icap.flags = ParseByte(capsData, ref curIdx);
                    icap.colConvBits = ParseByte(capsData, ref curIdx);
                    icap.transformBits = ParseByte(capsData, ref curIdx);
                    icap.entropyBits = (entropyBits_Value)ParseByte(capsData, ref curIdx);
                    icapList.Add(icap);
                }
                capSet.icapsData = icapList.ToArray();
                capSetList.Add(capSet);
            }
            caps.capsetsData = capSetList.ToArray();
            clientRFXCaps.capsData = caps;
            return clientRFXCaps;
        }
        /// <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();
        }