/// <summary> /// Calling this method to be notified when a new RPC connection is coming. /// </summary> /// <param name="ifMatchFunc">Matching function.</param> /// <param name="timeout">Timeout of expecting a connection.</param> /// <param name="sessionContext">The sessionContext of binded connection.</param> /// <returns>If bind succeeded, return true; otherwise, false.</returns> private bool InternalExpectBind( RpcIfMatchFunc ifMatchFunc, TimeSpan timeout, ref RpceServerSessionContext sessionContext) { RpcePdu receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext); RpceCoBindPdu bindPdu = receivedPdu as RpceCoBindPdu; if (bindPdu == null) { throw new InvalidOperationException("Expect bind_pdu, but received others."); } RpcIf rpcIf = new RpcIf(sessionContext.InterfaceId, sessionContext.InterfaceMajorVersion, sessionContext.InterfaceMinorVersion); if (!ifMatchFunc(rpcIf)) { // Interface doesn't match, response BindNak RpceCoBindNakPdu bindNakPdu = rpceServer.CreateCoBindNakPdu(sessionContext, p_reject_reason_t.REASON_NOT_SPECIFIED, null); FragmentAndSendPdu(sessionContext, bindNakPdu); return(false); } RpceCoBindAckPdu bindAckPdu = rpceServer.CreateCoBindAckPdu(sessionContext); FragmentAndSendPdu(sessionContext, bindAckPdu); while (sessionContext.SecurityContext != null && sessionContext.SecurityContextNeedContinueProcessing) { receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext); RpceCoAlterContextPdu alterContextPdu = receivedPdu as RpceCoAlterContextPdu; RpceCoAuth3Pdu auth3Pdu = receivedPdu as RpceCoAuth3Pdu; if (alterContextPdu != null) { RpceCoAlterContextRespPdu alterContextRespPdu = rpceServer.CreateCoAlterContextRespPdu(sessionContext); FragmentAndSendPdu(sessionContext, alterContextRespPdu); } else if (auth3Pdu != null) { //Do nothing } } return(true); }
/// <summary> /// Connect and bind to a RPCE remote host. /// </summary> /// <param name="protocolSequence"> /// A protocol sequence.<para/> /// Support ncacn_ip_tcp and ncacn_np only. /// </param> /// <param name="networkAddress"> /// A network address of RPCE remote host. /// </param> /// <param name="endpoint"> /// An endpoint that its format and content /// are associated with the protocol sequence. /// </param> /// <param name="transportCredential"> /// If connect by SMB/SMB2, it's the security credential /// used by underlayer transport (SMB/SMB2). /// If connect by TCP, this parameter is ignored. /// </param> /// <param name="interfaceId"> /// A Guid of interface_id that is binding to. /// </param> /// <param name="interfaceMajorVersion"> /// interface_major_ver that is binding to. /// </param> /// <param name="interfaceMinorVersion"> /// interface_minor_ver that is binding to. /// </param> /// <param name="securityContext"> /// A security provider. If setting to null, indicate the default authentication type NTLM is selected. /// </param> /// <param name="connectSecurityContext"> /// A security provider for connect authentication. If setting to null, indicate the default authentication type NTLM is selected. /// </param> /// <param name="authenticationLevel"> /// An authentication level. /// </param> /// <param name="supportsHeaderSign"> /// Indicates whether client supports header sign or not. /// </param> /// <param name="timeout"> /// Timeout period. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown when protSeq, networkAddr or endpoint is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when receive error from server. /// </exception> public virtual void Bind( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, Guid interfaceId, ushort interfaceMajorVersion, ushort interfaceMinorVersion, ClientSecurityContext securityContext, ClientSecurityContext connectSecurityContext, RpceAuthenticationLevel authenticationLevel, bool supportsHeaderSign, TimeSpan timeout) { if (protocolSequence == null) { throw new ArgumentNullException("protocolSequence"); } if (networkAddress == null) { throw new ArgumentNullException("networkAddress"); } if (endpoint == null) { throw new ArgumentNullException("endpoint"); } // RPC over named-pipe does not support asynchronous call in this library. // http://msdn.microsoft.com/en-us/library/windows/desktop/aa373551(v=vs.85).aspx rpceClient.Context.IsAsynchronous = (string.Compare(protocolSequence, RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, true) != 0); rpceClient.Connect(protocolSequence, networkAddress, endpoint, transportCredential, timeout, connectSecurityContext == null ? SecurityPackageType.Ntlm : connectSecurityContext.PackageType); rpceClient.SetAuthInfo(securityContext, authenticationLevel, rpceClient.Context.AuthenticationContextId); RpceCoBindPdu bindPdu = rpceClient.CreateCoBindPdu( //read from context, donot hardcode. rpceClient.Context.RpcVersionMinor, // default is rpc vers 5.0 supportsHeaderSign ? RpceCoPfcFlags.PFC_SUPPORT_HEADER_SIGN : RpceCoPfcFlags.None, rpceClient.ComputeNextCallId(), // call id, default is 1 rpceClient.Context.MaxTransmitFragmentSize, // max xmit frag rpceClient.Context.MaxReceiveFragmentSize, // max recv frag rpceClient.Context.AssociateGroupId, // assoc group id, default 0 interfaceId, interfaceMajorVersion, interfaceMinorVersion, rpceClient.Context.NdrVersion, // default is NDR (rpceClient.Context.BindTimeFeatureNegotiationBitmask != RpceBindTimeFeatureNegotiationBitmask.None) // default is None ? (RpceBindTimeFeatureNegotiationBitmask?)rpceClient.Context.BindTimeFeatureNegotiationBitmask : null); FragmentAndSendPdu(bindPdu); RpcePdu receivedPdu = ReceiveAndReassemblePdu(timeout); if (receivedPdu is RpceCoBindAckPdu) { if (rpceClient.Context.NdrVersion == RpceNdrVersion.None) { throw new InvalidOperationException("Neither NDR nor NDR64 is supported."); } } else { RpceCoBindNakPdu bindNakPdu = receivedPdu as RpceCoBindNakPdu; if (bindNakPdu != null) { throw new InvalidOperationException(bindNakPdu.provider_reject_reason.ToString()); } else { throw new InvalidOperationException( string.Format("Unexpected packet type received - {0}.", receivedPdu.GetType().Name)); } } while (rpceClient.Context.SecurityContext != null && rpceClient.Context.SecurityContext.NeedContinueProcessing) { RpceCoAlterContextPdu alterContextPdu = rpceClient.CreateCoAlterContextPdu(); FragmentAndSendPdu(alterContextPdu); receivedPdu = ReceiveAndReassemblePdu(timeout); RpceCoFaultPdu faultPdu = receivedPdu as RpceCoFaultPdu; if (faultPdu != null) { throw new InvalidOperationException(faultPdu.status.ToString()); } if (!(receivedPdu is RpceCoAlterContextRespPdu)) { throw new InvalidOperationException("Expect alter_context_pdu, but received others."); } } if (rpceClient.Context.SecurityContext != null && rpceClient.Context.SecurityContext.Token != null && rpceClient.Context.SecurityContext.Token.Length != 0) { RpceCoAuth3Pdu auth3Pdu = rpceClient.CreateCoAuth3Pdu(); FragmentAndSendPdu(auth3Pdu); // no expected response from server rpceClient.Context.OutstandingCalls.Remove(auth3Pdu.call_id); } if (rpceClient.Context.IsAsynchronous) { // Start the receiving thread to receive the response from server. cancellationToken = new CancellationTokenSource(); receiveTask = new Task(EventLoop, cancellationToken.Token); //new Thread(new ThreadStart(EventLoop)); //receiveThread.IsBackground = true; receiveTask.Start(); } }
/// <summary> /// update context on receiving RPCE CO Bind PDU. /// </summary> /// <param name="bindPdu">Bind PDU to receive.</param> internal void UpdateContextOnReceivingBindPdu(RpceCoBindPdu bindPdu) { this.MaxTransmitFragmentSize = bindPdu.max_xmit_frag; this.MaxReceiveFragmentSize = bindPdu.max_recv_frag; if (bindPdu.assoc_group_id != 0) { this.AssociateGroupId = bindPdu.assoc_group_id; } else { if (this.associateGroupIdList.Count == 0) { this.AssociateGroupId = bindPdu.assoc_group_id + 1; } else { this.associateGroupIdList.Sort(); this.AssociateGroupId = this.associateGroupIdList[this.associateGroupIdList.Count - 1] + 1; } } associateGroupIdList.Add(this.AssociateGroupId); if (bindPdu.p_context_elem.p_cont_elem != null && bindPdu.p_context_elem.p_cont_elem.Length > 0) { this.InterfaceId = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid; this.InterfaceMajorVersion = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_vers_major; this.InterfaceMinorVersion = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_vers_minor; this.NdrVersion = RpceNdrVersion.None; this.PresentationContextsTable.Clear(); for (int i = 0; i < bindPdu.p_context_elem.p_cont_elem.Length; i++) { p_cont_elem_t p_cont_elem = bindPdu.p_context_elem.p_cont_elem[i]; if (p_cont_elem.transfer_syntaxes == null) { continue; } for (int j = 0; j < p_cont_elem.transfer_syntaxes.Length; j++) { p_syntax_id_t transfer_syntax = p_cont_elem.transfer_syntaxes[j]; if (transfer_syntax.if_uuid == RpceUtility.NDR_INTERFACE_UUID && transfer_syntax.if_vers_major == RpceUtility.NDR_INTERFACE_MAJOR_VERSION && transfer_syntax.if_vers_minor == RpceUtility.NDR_INTERFACE_MINOR_VERSION) { this.NdrVersion |= RpceNdrVersion.NDR; this.PresentationContextsTable.Add(p_cont_elem.p_cont_id, RpceNdrVersion.NDR); } else if (transfer_syntax.if_uuid == RpceUtility.NDR64_INTERFACE_UUID && transfer_syntax.if_vers_major == RpceUtility.NDR64_INTERFACE_MAJOR_VERSION && transfer_syntax.if_vers_minor == RpceUtility.NDR64_INTERFACE_MINOR_VERSION) { this.NdrVersion |= RpceNdrVersion.NDR64; this.PresentationContextsTable.Add(p_cont_elem.p_cont_id, RpceNdrVersion.NDR64); } else { byte[] uuid = transfer_syntax.if_uuid.ToByteArray(); if (ArrayUtility.CompareArrays( ArrayUtility.SubArray( uuid, 0, RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH), ArrayUtility.SubArray( RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_GUID_BYTES, 0, RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH)) && transfer_syntax.if_vers_major == 1 && transfer_syntax.if_vers_minor == 0) { this.BindTimeFeatureNegotiationBitmask = (RpceBindTimeFeatureNegotiationBitmask) uuid[RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH]; } } } } } }
/// <summary> /// update context on receiving PDU. /// </summary> /// <param name="pdu">PDU to receive.</param> /// <exception cref="ArgumentNullException">Thrown when pdu is null.</exception> internal void UpdateContextOnReceivingPdu(RpcePdu pdu) { RpceCoPdu coPdu = pdu as RpceCoPdu; if (coPdu == null) { return; } this.RpcVersionMajor = coPdu.rpc_vers; this.RpcVersionMinor = coPdu.rpc_vers_minor; if (coPdu.PTYPE == RpcePacketType.Bind || coPdu.PTYPE == RpcePacketType.BindAck) { //TDI: //TD said PFC_SUPPORT_HEADER_SIGN is meanful in Bind and AltContext. //But when using Kerberos, AltContext doesn't have this flag, //if server or client read this flag according to AltContext, Sign/Encrypt will fail. this.SupportsHeaderSign = (coPdu.pfc_flags & RpceCoPfcFlags.PFC_SUPPORT_HEADER_SIGN) == RpceCoPfcFlags.PFC_SUPPORT_HEADER_SIGN; this.SupportsConcurrentMultiplexing = (coPdu.pfc_flags & RpceCoPfcFlags.PFC_CONC_MPX) == RpceCoPfcFlags.PFC_CONC_MPX; } this.PackedDataRepresentationFormat = coPdu.packed_drep.dataRepFormat; this.CurrentCallId = coPdu.call_id; if (coPdu.PTYPE != RpcePacketType.Response && coPdu.PTYPE != RpcePacketType.Auth3) { this.outstandingCalls.Add(coPdu.call_id); } switch (coPdu.PTYPE) { case RpcePacketType.Bind: RpceCoBindPdu bindPdu = coPdu as RpceCoBindPdu; if (bindPdu != null) { UpdateContextOnReceivingBindPdu(bindPdu); } break; case RpcePacketType.Request: RpceCoRequestPdu requestPdu = coPdu as RpceCoRequestPdu; if (requestPdu != null) { this.ContextIdentifier = requestPdu.p_cont_id; } break; case RpcePacketType.Response: RpceCoResponsePdu responsePdu = coPdu as RpceCoResponsePdu; if (responsePdu != null) { this.ContextIdentifier = responsePdu.p_cont_id; } break; case RpcePacketType.Auth3: case RpcePacketType.AlterContext: case RpcePacketType.CoCancel: case RpcePacketType.Orphaned: default: //default situation should do nothing. //This is just update the context, if we cannot recognize the PDU, ignore it. break; } this.SecurityContextNeedContinueProcessing = coPdu.securityContextNeedContinueProcessing; }
public static RpceCoPdu DecodeCoPdu( RpceContext context, byte[] pduBytes) { if (context == null) { throw new ArgumentNullException("context"); } if (pduBytes == null) { throw new ArgumentNullException("pduBytes"); } RpceCoPdu pdu; //#2 byte is PTYPE RpcePacketType packageType = (RpcePacketType)pduBytes[2]; //#3 byte is PFC_*** flags RpceCoPfcFlags pfcFlags = (RpceCoPfcFlags)pduBytes[3]; RpceCoPfcFlags pfcFlagsNoFragment = RpceCoPfcFlags.PFC_FIRST_FRAG | RpceCoPfcFlags.PFC_LAST_FRAG; if (((pfcFlags & pfcFlagsNoFragment) != pfcFlagsNoFragment) && (packageType == RpcePacketType.Bind || packageType == RpcePacketType.BindAck || packageType == RpcePacketType.AlterContext || packageType == RpcePacketType.AlterContextResp || packageType == RpcePacketType.Auth3)) { //If it's a fragment and PTYPE is bind/bind_ack/alter_context/alter_context_resp //Windows RPC support version 5.0 only. //Bind fragment requires RPC ver 5.1. //We don't support it. throw new NotSupportedException("bind/bind_ack/alt_context/alt_context_resp/auth3 PDU fragment are not supported."); } else { switch (packageType) { case RpcePacketType.Bind: pdu = new RpceCoBindPdu(context, pduBytes); break; case RpcePacketType.BindAck: pdu = new RpceCoBindAckPdu(context, pduBytes); break; case RpcePacketType.BindNak: pdu = new RpceCoBindNakPdu(context, pduBytes); break; case RpcePacketType.AlterContext: pdu = new RpceCoAlterContextPdu(context, pduBytes); break; case RpcePacketType.AlterContextResp: pdu = new RpceCoAlterContextRespPdu(context, pduBytes); break; case RpcePacketType.Auth3: pdu = new RpceCoAuth3Pdu(context, pduBytes); break; case RpcePacketType.Request: pdu = new RpceCoRequestPdu(context, pduBytes); break; case RpcePacketType.Response: pdu = new RpceCoResponsePdu(context, pduBytes); break; case RpcePacketType.Fault: pdu = new RpceCoFaultPdu(context, pduBytes); break; case RpcePacketType.CoCancel: pdu = new RpceCoCancelPdu(context, pduBytes); break; case RpcePacketType.Orphaned: pdu = new RpceCoOrphanedPdu(context, pduBytes); break; case RpcePacketType.Shutdown: pdu = new RpceCoShutdownPdu(context, pduBytes); break; default: throw new InvalidOperationException( string.Format("Receive invalid packet - {0}.", packageType)); } } return(pdu); }
/// <summary> /// Create an RpceCoBindPdu. /// </summary> /// <param name="rpcVersionMinor"> /// RPC version minor. /// </param> /// <param name="pfcFlags"> /// PFC_*** flags. /// </param> /// <param name="callId"> /// Call Id. /// </param> /// <param name="maxTransmitFragmentSize"> /// Max transmit fragment size, in bytes. /// </param> /// <param name="maxReceiveFragmentSize"> /// Max receive fragment size, in bytes. /// </param> /// <param name="associateGroupId"> /// Associated group id. /// </param> /// <param name="interfaceId"> /// A Guid of interface_id that is binding to. /// </param> /// <param name="interfaceMajorVersion"> /// interface_major_ver that is binding to. /// </param> /// <param name="interfaceMinorVersion"> /// interface_minor_ver that is binding to. /// </param> /// <param name="ndrVersion"> /// NDR version to be used to marshal/un-marshal stub. /// </param> /// <param name="bindTimeFeatureNegotiationBitmask"> /// BindTimeFeatureNegotiationBitmask to sent. /// Set the value to null if client donot support the feature. /// </param> /// <returns> /// Created RpceCoBindPdu, it's ok to be sent out if there's /// no modification to any field of the PDU. /// </returns> public RpceCoBindPdu CreateCoBindPdu( byte rpcVersionMinor, RpceCoPfcFlags pfcFlags, uint callId, ushort maxTransmitFragmentSize, ushort maxReceiveFragmentSize, uint associateGroupId, Guid interfaceId, ushort interfaceMajorVersion, ushort interfaceMinorVersion, RpceNdrVersion ndrVersion, RpceBindTimeFeatureNegotiationBitmask? bindTimeFeatureNegotiationBitmask) { RpceCoBindPdu bindPdu = new RpceCoBindPdu(context); bindPdu.rpc_vers = 5; bindPdu.rpc_vers_minor = rpcVersionMinor; bindPdu.PTYPE = RpcePacketType.Bind; bindPdu.pfc_flags = pfcFlags | RpceCoPfcFlags.PFC_FIRST_FRAG | RpceCoPfcFlags.PFC_LAST_FRAG; bindPdu.packed_drep.dataRepFormat = RpceDataRepresentationFormat.IEEE_LittleEndian_ASCII; bindPdu.packed_drep.reserved = 0; bindPdu.call_id = callId; bindPdu.max_xmit_frag = maxTransmitFragmentSize; bindPdu.max_recv_frag = maxReceiveFragmentSize; bindPdu.assoc_group_id = associateGroupId; List<p_cont_elem_t> p_cont_elem_list = new List<p_cont_elem_t>(); if ((ndrVersion & RpceNdrVersion.NDR) == RpceNdrVersion.NDR) { p_cont_elem_t p_cont_elem; p_cont_elem.p_cont_id = (ushort)(p_cont_elem_list.Count); p_cont_elem.n_transfer_syn = 1; p_cont_elem.reserved = 0; p_cont_elem.abstract_syntax.if_uuid = interfaceId; p_cont_elem.abstract_syntax.if_vers_major = interfaceMajorVersion; p_cont_elem.abstract_syntax.if_vers_minor = interfaceMinorVersion; p_cont_elem.transfer_syntaxes = new p_syntax_id_t[1]; p_cont_elem.transfer_syntaxes[0].if_uuid = RpceUtility.NDR_INTERFACE_UUID; p_cont_elem.transfer_syntaxes[0].if_vers_major = RpceUtility.NDR_INTERFACE_MAJOR_VERSION; p_cont_elem.transfer_syntaxes[0].if_vers_minor = RpceUtility.NDR_INTERFACE_MINOR_VERSION; p_cont_elem_list.Add(p_cont_elem); } if ((ndrVersion & RpceNdrVersion.NDR64) == RpceNdrVersion.NDR64) { p_cont_elem_t p_cont_elem; p_cont_elem.p_cont_id = (ushort)(p_cont_elem_list.Count); p_cont_elem.n_transfer_syn = 1; p_cont_elem.reserved = 0; p_cont_elem.abstract_syntax.if_uuid = interfaceId; p_cont_elem.abstract_syntax.if_vers_major = interfaceMajorVersion; p_cont_elem.abstract_syntax.if_vers_minor = interfaceMinorVersion; p_cont_elem.transfer_syntaxes = new p_syntax_id_t[1]; p_cont_elem.transfer_syntaxes[0].if_uuid = RpceUtility.NDR64_INTERFACE_UUID; p_cont_elem.transfer_syntaxes[0].if_vers_major = RpceUtility.NDR64_INTERFACE_MAJOR_VERSION; p_cont_elem.transfer_syntaxes[0].if_vers_minor = RpceUtility.NDR64_INTERFACE_MINOR_VERSION; p_cont_elem_list.Add(p_cont_elem); } if (bindTimeFeatureNegotiationBitmask != null) { p_cont_elem_t p_cont_elem; p_cont_elem.p_cont_id = (ushort)(p_cont_elem_list.Count); p_cont_elem.n_transfer_syn = 1; p_cont_elem.reserved = 0; p_cont_elem.abstract_syntax.if_uuid = interfaceId; p_cont_elem.abstract_syntax.if_vers_major = interfaceMajorVersion; p_cont_elem.abstract_syntax.if_vers_minor = interfaceMinorVersion; p_cont_elem.transfer_syntaxes = new p_syntax_id_t[1]; byte[] guidBytes = new byte[RpceUtility.GUID_SIZE]; // length of a Guid Buffer.BlockCopy( RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_GUID_BYTES, 0, guidBytes, 0, RpceUtility.GUID_SIZE); guidBytes[RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH] = (byte)bindTimeFeatureNegotiationBitmask.Value; p_cont_elem.transfer_syntaxes[0].if_uuid = new Guid(guidBytes); p_cont_elem.transfer_syntaxes[0].if_vers_major = 1; p_cont_elem.transfer_syntaxes[0].if_vers_minor = 0; p_cont_elem_list.Add(p_cont_elem); } bindPdu.p_context_elem.n_context_elem = (byte)p_cont_elem_list.Count; bindPdu.p_context_elem.reserved = 0; bindPdu.p_context_elem.reserved2 = 0; bindPdu.p_context_elem.p_cont_elem = p_cont_elem_list.ToArray(); bindPdu.AppendAuthenticationVerifier(); bindPdu.SetLength(); return bindPdu; }
/// <summary> /// update context on sending RPCE CO Bind PDU /// </summary> /// <param name="bindPdu">Bind PDU</param> private void UpdateContextOnSendingBindPdu(RpceCoBindPdu bindPdu) { context.MaxTransmitFragmentSize = bindPdu.max_xmit_frag; context.MaxReceiveFragmentSize = bindPdu.max_recv_frag; context.AssociateGroupId = bindPdu.assoc_group_id; if (bindPdu.p_context_elem.p_cont_elem != null && bindPdu.p_context_elem.p_cont_elem.Length > 0) { context.InterfaceId = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid; context.InterfaceMajorVersion = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_vers_major; context.InterfaceMinorVersion = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_vers_minor; context.NdrVersion = RpceNdrVersion.None; context.PresentationContextsTable.Clear(); for (int i = 0; i < bindPdu.p_context_elem.p_cont_elem.Length; i++) { if (bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes == null) { continue; } for (int j = 0; j < bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes.Length; j++) { if (bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_uuid == RpceUtility.NDR_INTERFACE_UUID && bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_vers_major == RpceUtility.NDR_INTERFACE_MAJOR_VERSION && bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_vers_minor == RpceUtility.NDR_INTERFACE_MINOR_VERSION) { context.NdrVersion |= RpceNdrVersion.NDR; context.PresentationContextsTable.Add( bindPdu.p_context_elem.p_cont_elem[i].p_cont_id, RpceNdrVersion.NDR); } else if (bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_uuid == RpceUtility.NDR64_INTERFACE_UUID && bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_vers_major == RpceUtility.NDR64_INTERFACE_MAJOR_VERSION && bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_vers_minor == RpceUtility.NDR64_INTERFACE_MINOR_VERSION) { context.NdrVersion |= RpceNdrVersion.NDR64; context.PresentationContextsTable.Add( bindPdu.p_context_elem.p_cont_elem[i].p_cont_id, RpceNdrVersion.NDR64); } else { byte[] uuid = bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_uuid.ToByteArray(); if (ArrayUtility.CompareArrays( ArrayUtility.SubArray( uuid, 0, RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH), ArrayUtility.SubArray( RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_GUID_BYTES, 0, RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH)) && bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_vers_major == 1 && bindPdu.p_context_elem.p_cont_elem[i].transfer_syntaxes[j].if_vers_minor == 0) { context.BindTimeFeatureNegotiationBitmask = (RpceBindTimeFeatureNegotiationBitmask) uuid[RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH]; } } } } } }