The server announces its capabilities and requests the same from the client.
file:///D:/programs/RFSPAC/XML-RDPEFS/_rfc_ms-rdpefs2_2_2_7.xml
        /// <summary>
        /// Create Server Core Capability Request packet.
        /// </summary>
        /// <returns>Server Core Capability Request packet.</returns>
        public static DR_CORE_CAPABILITY_REQ CreateServerCoreCapabilityRequest()
        {
            DR_CORE_CAPABILITY_REQ request = new DR_CORE_CAPABILITY_REQ();
            request.Header = new RDPDR_HEADER();
            request.Header.Component = Component_Values.RDPDR_CTYP_CORE;
            request.Header.PacketId = PacketId_Values.PAKID_CORE_SERVER_CAPABILITY;
            request.numCapabilities = 5;
            request.Padding = 0;

            List<CAPABILITY_SET> capabilitySet = new List<CAPABILITY_SET>();

            GENERAL_CAPS_SET generalCapability = new GENERAL_CAPS_SET();
            generalCapability.Header = new CAPABILITY_HEADER();
            generalCapability.Header.CapabilityType = CapabilityType_Values.CAP_GENERAL_TYPE;
            generalCapability.Header.CapabilityLength = 44;
            generalCapability.Header.Version = CAPABILITY_VERSION.V1;
            generalCapability.osType = osType_Values.OS_TYPE_UNKNOWN;
            generalCapability.osVersion = osVersion_Values.V1;
            generalCapability.protocolMajorVersion = protocolMajorVersion_Values.V1;
            generalCapability.protocolMinorVersion = 0x000C;
            generalCapability.ioCode1 = (ioCode1_Values)0x0000FFFF;
            generalCapability.ioCode2 = ioCode2_Values.V1;
            generalCapability.extendedPDU = extendedPDU_Values.RDPDR_DEVICE_REMOVE_PDUS | extendedPDU_Values.RDPDR_CLIENT_DISPLAY_NAME_PDU;
            generalCapability.extraFlags1 = extraFlags1_Values.ENABLE_ASYNCIO;
            generalCapability.extraFlags2 = extraFlags2_Values.V1;
            generalCapability.SpecialTypeDeviceCap = 2;
            capabilitySet.Add(generalCapability);

            PRINTER_CAPS_SET printerCapability = new PRINTER_CAPS_SET();
            printerCapability.Header = new CAPABILITY_HEADER();
            printerCapability.Header.CapabilityType = CapabilityType_Values.CAP_PRINTER_TYPE;
            printerCapability.Header.CapabilityLength = 8;
            printerCapability.Header.Version = CAPABILITY_VERSION.V1;
            capabilitySet.Add(printerCapability);

            PORT_CAPS_SET portCapability = new PORT_CAPS_SET();
            portCapability.Header = new CAPABILITY_HEADER();
            portCapability.Header.CapabilityType = CapabilityType_Values.CAP_PORT_TYPE;
            portCapability.Header.CapabilityLength = 8;
            portCapability.Header.Version = CAPABILITY_VERSION.V1;
            capabilitySet.Add(portCapability);

            DRIVE_CAPS_SET driveCapability = new DRIVE_CAPS_SET();
            driveCapability.Header = new CAPABILITY_HEADER();
            driveCapability.Header.CapabilityType = CapabilityType_Values.CAP_DRIVE_TYPE;
            driveCapability.Header.CapabilityLength = 8;
            driveCapability.Header.Version = CAPABILITY_VERSION.V2;
            capabilitySet.Add(driveCapability);

            SMARTCARD_CAPS_SET smartcardCapability = new SMARTCARD_CAPS_SET();
            smartcardCapability.Header = new CAPABILITY_HEADER();
            smartcardCapability.Header.CapabilityType = CapabilityType_Values.CAP_SMARTCARD_TYPE;
            smartcardCapability.Header.CapabilityLength = 8;
            smartcardCapability.Header.Version = CAPABILITY_VERSION.V1;
            capabilitySet.Add(smartcardCapability);

            request.CapabilityMessage = capabilitySet.ToArray();
            return request;
        }
        /// <summary>
        /// Encode Server Core Capability Request packet.
        /// </summary>
        /// <param name="packet">Server Core Capability Request packet.</param>
        /// <returns>Encoded byte array.</returns>
        public static byte[] EncodeServerCoreCapabilityRequest(DR_CORE_CAPABILITY_REQ packet)
        {
            List<byte> buffer = new List<byte>();
            EncodeStructure(buffer, (ushort)packet.Header.Component);
            EncodeStructure(buffer, (ushort)packet.Header.PacketId);
            EncodeStructure(buffer, packet.numCapabilities);
            EncodeStructure(buffer, packet.Padding);

            if (packet.CapabilityMessage != null)
            {
                foreach (CAPABILITY_SET capability in packet.CapabilityMessage)
                {
                    if (capability is GENERAL_CAPS_SET)
                    {
                        GENERAL_CAPS_SET generalCapability = capability as GENERAL_CAPS_SET;
                        EncodeStructure(buffer, (ushort)generalCapability.Header.CapabilityType);
                        EncodeStructure(buffer, (ushort)generalCapability.Header.CapabilityLength);
                        EncodeStructure(buffer, (uint)generalCapability.Header.Version);
                        EncodeStructure(buffer, (uint)generalCapability.osType);
                        EncodeStructure(buffer, (uint)generalCapability.osVersion);
                        EncodeStructure(buffer, (ushort)generalCapability.protocolMajorVersion);
                        EncodeStructure(buffer, (ushort)generalCapability.protocolMinorVersion);
                        EncodeStructure(buffer, (uint)generalCapability.ioCode1);
                        EncodeStructure(buffer, (uint)generalCapability.ioCode2);
                        EncodeStructure(buffer, (uint)generalCapability.extendedPDU);
                        EncodeStructure(buffer, (uint)generalCapability.extraFlags1);
                        EncodeStructure(buffer, (uint)generalCapability.extraFlags2);
                        EncodeStructure(buffer, (uint)generalCapability.SpecialTypeDeviceCap);
                    }
                    else
                    {
                        EncodeStructure(buffer, (ushort)capability.Header.CapabilityType);
                        EncodeStructure(buffer, (ushort)capability.Header.CapabilityLength);
                        EncodeStructure(buffer, (uint)capability.Header.Version);
                    }
                }
            }

            return buffer.ToArray();
        }