The Font List PDU is a Standard RDP Connection Sequence PDU sent from client to server during the Connection Finalization phase (see section ). It is sent after transmitting a Persistent Key List PDU or, if the Persistent Key List PDU was not sent, it is sent after transmitting the Client Control PDU (Request Control).
file:///C:/ts_dev/TestSuites/MS-RDPBCGR/TestSuite/Src/TD/latest_XMLS_16may/RDPBCGR/ _rfc_ms-rdpbcgr2_1_1_18.xml
Inheritance: RdpbcgrClientPdu
        /// <summary>
        /// Decode Font List PDU
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <param name="decryptedUserData">decrypted user data to be parsed</param>
        /// <param name="type">security header type</param>
        /// <returns>decoded Font List PDU</returns>
        public StackPacket DecodeFontListPDU(
            byte[] data,
            byte[] decryptedUserData,
            SecurityHeaderType type)
        {
            Client_Font_List_Pdu pdu = new Client_Font_List_Pdu();

            // data index
            int dataIndex = 0;

            // FontMapPDU: commonHeader
            pdu.commonHeader = ParseMcsCommonHeader(data, ref dataIndex, type);

            // user data index
            int userDataIndex = 0;

            // FontMapPDU: fontMapPduData
            pdu.fontListPduData = ParseTsFontListPdu(decryptedUserData, ref userDataIndex);

            // ETW Provider Dump Message
            if (pdu.commonHeader.securityHeader != null)
            {
                // RDP Standard Security
                string messageName = "RDPBCGR:" + pdu.GetType().Name;
                ExtendedLogger.DumpMessage(messageName, RdpbcgrUtility.DumpLevel_Layer3, pdu.GetType().Name, decryptedUserData);
            }

            // Check if data length exceeded expectation
            VerifyDataLength(decryptedUserData.Length, userDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED);
            return pdu;
        }
        /// <summary>
        /// 2.2.1.18
        /// </summary>
        /// <param name="fontListPdu"></param>
        public void VerifyPdu(Client_Font_List_Pdu fontListPdu)
        {
            if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT ||
                serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT ||
                serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT)
            {
                site.CaptureRequirementIfIsInstanceOfType(fontListPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER1), 845,
                    @"In Client Font List PDU, securityHeader (variable): The securityHeader in Server Demand Active PDU is a Non-FIPS"
                    + @" Security Header (section 2.2.8.1.1.2.2) if the Encryption LevelMethod selected by the server (see sections 5.3.2"
                    + @" and 2.2.1.4.3) is ENCRYPTION_LEVEL_CLIENT_COMPATIBLE (2)METHOD_40BIT (0x00000001), ENCRYPTION_METHOD_56BIT "
                    + @"(0x00000008), or ENCRYPTION_LEVEL_HIGH (3METHOD_128BIT (0x00000002).");
            }
            else if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS)
            {
                site.CaptureRequirementIfIsInstanceOfType(fontListPdu.commonHeader.securityHeader, typeof(TS_SECURITY_HEADER2), 846,
                    @"In Client Font List PDU, securityHeader (variable): The securityHeader in Server Demand Active PDU is a FIPS Security"
                    + @" Header,if the Encryption LevelMethod selected by the server is ENCRYPTION_METHOD_FIPS (0x00000010).");
            }
            else if (serverConfig.encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_NONE)
            {
                site.CaptureRequirementIfIsNull(fontListPdu.commonHeader.securityHeader, 847,
                    @"In the Client Font List PDU, if Enhanced RDP Security is in effect or the Encryption Method selected by the server "
                    + @"is ENCRYPTION_METHOD_NONE (0), then securityHeader MUST NOT be included in the Client Font List PDU.");
            }

            site.CaptureRequirementIfAreEqual<int>(7, (fontListPdu.fontListPduData.shareDataHeader.shareControlHeader.pduType.typeAndVersionLow & 0xf), 851,
                @"In TS_FONT_LIST_PDU, the type subfield of the pduType field of the Share Control Header MUST be set to PDUTYPE_DATAPDU (7).");

            site.CaptureRequirementIfAreEqual<pduType2_Values>(pduType2_Values.PDUTYPE2_FONTLIST, fontListPdu.fontListPduData.shareDataHeader.pduType2, 852,
                @"In TS_FONT_LIST_PDU, the pduType2 field of the Share Data Header MUST be set to PDUTYPE2_FONTLIST (39).");

            //2.2.1.18.1
            site.CaptureRequirementIfAreEqual<ushort>(0, fontListPdu.fontListPduData.numberFonts, 854,
                @"In TS_FONT_LIST_PDU, numberFonts field SHOULD be set to 0.");
            site.CaptureRequirementIfAreEqual<ushort>(0, fontListPdu.fontListPduData.totalNumFonts, 856,
                @"In TS_FONT_LIST_PDU, totalNumFonts field SHOULD be set to 0.");
            site.CaptureRequirementIfAreEqual<ushort>(0x0003, fontListPdu.fontListPduData.listFlags, 858,
                @"In TS_FONT_LIST_PDU, listFlags field SHOULD be set to 0x0003 which is the logical OR'ed value of FONTLIST_FIRST (0x0001)"
                + @" and FONTLIST_LAST (0x0002).");
            site.CaptureRequirementIfAreEqual<ushort>(0x0032, fontListPdu.fontListPduData.entrySize, 860,
                @"In TS_FONT_LIST_PDU, entrySize field SHOULD be set to 0x0032 (50 bytes).");
        }
        /// <summary>
        /// Create an instance of the class that is identical to the current PDU. 
        /// </summary>
        /// <returns>The new instance.</returns>
        public override StackPacket Clone()
        {
            Client_Font_List_Pdu cloneFontListPdu = new Client_Font_List_Pdu(context);
            cloneFontListPdu.commonHeader = commonHeader.Clone();

            if (fontListPduData != null)
            {
                cloneFontListPdu.fontListPduData = new TS_FONT_LIST_PDU();
                cloneFontListPdu.fontListPduData.shareDataHeader = fontListPduData.shareDataHeader;
                cloneFontListPdu.fontListPduData.entrySize = fontListPduData.entrySize;
                cloneFontListPdu.fontListPduData.listFlags = fontListPduData.listFlags;
                cloneFontListPdu.fontListPduData.numberFonts = fontListPduData.numberFonts;
                cloneFontListPdu.fontListPduData.totalNumFonts = fontListPduData.totalNumFonts;
            }

            return cloneFontListPdu;
        }