/// <summary>
        /// Un-marshal a byte array to PDU struct.
        /// </summary>
        /// <param name="binaryReader">BinaryReader</param>
        internal override void FromBytes(BinaryReader binaryReader)
        {
            base.FromBytes(binaryReader);

            provider_reject_reason = (p_reject_reason_t)binaryReader.ReadUInt16();
            versions             = new p_rt_versions_supported_t();
            versions.n_protocols = binaryReader.ReadByte();
            versions.p_protocols = new version_t[versions.n_protocols];
            for (int i = 0; i < versions.n_protocols; i++)
            {
                versions.p_protocols[i].major = binaryReader.ReadByte();
                versions.p_protocols[i].minor = binaryReader.ReadByte();
            }

            //Assume that the client calculates the length of the PDU
            //until the Signature field as L.
            //If the frag_length field is greater than or equal to L
            //plus the size of the Signature field,
            //the client SHOULD assume that the Signature field is present.
            //Otherwise, the client SHOULD assume that the Signature field is not present.
            //TD shows the signature is aligned at 4.
            int L = RpceUtility.Align((int)binaryReader.BaseStream.Position, 4);

            if (frag_length >= (L + RpceUtility.GUID_SIZE))
            {
                pad                 = binaryReader.ReadBytes(L - (int)binaryReader.BaseStream.Position);
                signature           = new Guid(binaryReader.ReadBytes(RpceUtility.GUID_SIZE));
                extended_error_info = binaryReader.ReadBytes(frag_length - L - RpceUtility.GUID_SIZE);
            }
        }
        public RpceCoBindNakPdu CreateCoBindNakPdu(
            RpceServerSessionContext sessionContext,
            p_reject_reason_t rejectReason,
            byte[] extendedErrorInfo)
        {
            if (sessionContext == null)
            {
                throw new ArgumentNullException("sessionContext");
            }

            RpceCoBindNakPdu bindNakPdu = new RpceCoBindNakPdu(sessionContext);

            bindNakPdu.rpc_vers = sessionContext.RpcVersionMajor;
            bindNakPdu.rpc_vers_minor = sessionContext.RpcVersionMinor;
            bindNakPdu.PTYPE = RpcePacketType.BindNak;
            bindNakPdu.pfc_flags = RpceUtility.GeneratePfcFlags(sessionContext, RpcePacketType.BindNak);
            bindNakPdu.packed_drep.dataRepFormat = sessionContext.PackedDataRepresentationFormat;
            bindNakPdu.packed_drep.reserved = 0;
            bindNakPdu.call_id = sessionContext.CurrentCallId;

            bindNakPdu.provider_reject_reason = rejectReason;
            bindNakPdu.versions.n_protocols = 1; // only one rpc version in server context.
            bindNakPdu.versions.p_protocols = new version_t[bindNakPdu.versions.n_protocols];
            // It's the supported rpc versions, so we response version number in server context.
            bindNakPdu.versions.p_protocols[0].major = sessionContext.ServerContext.RpcVersionMajor;
            bindNakPdu.versions.p_protocols[0].major = sessionContext.ServerContext.RpcVersionMinor;

            int sizeOfReasonAndVersions = Marshal.SizeOf(typeof(ushort)); // bindNakPdu.provider_reject_reason
            sizeOfReasonAndVersions += Marshal.SizeOf(bindNakPdu.versions.n_protocols);
            sizeOfReasonAndVersions += Marshal.SizeOf(typeof(version_t)) * bindNakPdu.versions.n_protocols;
            bindNakPdu.pad = new byte[RpceUtility.Align(sizeOfReasonAndVersions, 4) - sizeOfReasonAndVersions];

            if (extendedErrorInfo != null)
            {
                bindNakPdu.signature = RpceUtility.BINDNAK_SIGNATURE;
                bindNakPdu.extended_error_info = extendedErrorInfo;
            }

            bindNakPdu.SetLength();

            return bindNakPdu;
        }
        /// <summary>
        /// Un-marshal a byte array to PDU struct.
        /// </summary>
        /// <param name="binaryReader">BinaryReader</param>
        internal override void FromBytes(BinaryReader binaryReader)
        {
            base.FromBytes(binaryReader);

            provider_reject_reason = (p_reject_reason_t)binaryReader.ReadUInt16();
            versions = new p_rt_versions_supported_t();
            versions.n_protocols = binaryReader.ReadByte();
            versions.p_protocols = new version_t[versions.n_protocols];
            for (int i = 0; i < versions.n_protocols; i++)
            {
                versions.p_protocols[i].major = binaryReader.ReadByte();
                versions.p_protocols[i].minor = binaryReader.ReadByte();
            }

            //Assume that the client calculates the length of the PDU
            //until the Signature field as L.
            //If the frag_length field is greater than or equal to L
            //plus the size of the Signature field,
            //the client SHOULD assume that the Signature field is present.
            //Otherwise, the client SHOULD assume that the Signature field is not present.
            //TD shows the signature is aligned at 4.
            int L = RpceUtility.Align((int)binaryReader.BaseStream.Position, 4);
            if (frag_length >= (L + RpceUtility.GUID_SIZE))
            {
                pad = binaryReader.ReadBytes(L - (int)binaryReader.BaseStream.Position);
                signature = new Guid(binaryReader.ReadBytes(RpceUtility.GUID_SIZE));
                extended_error_info = binaryReader.ReadBytes(frag_length - L - RpceUtility.GUID_SIZE);
            }
        }