void SetClaimsPrincipalToOperationContext(MessageRpc rpc)
        {
            ServiceSecurityContext securityContext = rpc.SecurityContext;

            if (!rpc.HasSecurityContext)
            {
                SecurityMessageProperty securityContextProperty = rpc.Request.Properties.Security;
                if (securityContextProperty != null)
                {
                    securityContext = securityContextProperty.ServiceSecurityContext;
                }
            }

            if (securityContext != null)
            {
                object principal;
                if (securityContext.AuthorizationContext.Properties.TryGetValue(AuthorizationPolicy.ClaimsPrincipalKey, out principal))
                {
                    ClaimsPrincipal claimsPrincipal = principal as ClaimsPrincipal;
                    if (claimsPrincipal != null)
                    {
                        //
                        // Always set ClaimsPrincipal to OperationContext.Current if identityModel pipeline is used.
                        //
                        OperationContext.Current.ClaimsPrincipal = claimsPrincipal;
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoPrincipalSpecifiedInAuthorizationContext)));
                    }
                }
            }
        }
        void InspectInputsCore(ref MessageRpc rpc)
        {
            int       offset       = this.Parent.ParameterInspectorCorrelationOffset;
            bool      outputTiming = DS.ParameterInspectorIsEnabled();
            Stopwatch sw           = null;

            if (outputTiming)
            {
                sw = new Stopwatch();
            }

            for (int i = 0; i < this.ParameterInspectors.Length; i++)
            {
                IParameterInspector inspector = this.ParameterInspectors[i];
                if (outputTiming)
                {
                    sw.Restart();
                }

                rpc.Correlation[offset + i] = inspector.BeforeCall(this.Name, rpc.InputParameters);
                if (outputTiming)
                {
                    DS.ParameterInspectorBefore(inspector.GetType(), sw.Elapsed);
                }

                if (TD.ParameterInspectorBeforeCallInvokedIsEnabled())
                {
                    TD.ParameterInspectorBeforeCallInvoked(rpc.EventTraceActivity, inspector.GetType().FullName);
                }
            }
        }
        void InspectOutputsCore(ref MessageRpc rpc)
        {
            int       offset       = this.Parent.ParameterInspectorCorrelationOffset;
            bool      outputTiming = DS.ParameterInspectorIsEnabled();
            Stopwatch sw           = null;

            if (outputTiming)
            {
                sw = new Stopwatch();
            }

            for (int i = this.ParameterInspectors.Length - 1; i >= 0; i--)
            {
                IParameterInspector inspector = this.ParameterInspectors[i];
                if (outputTiming)
                {
                    sw.Restart();
                }

                inspector.AfterCall(this.Name, rpc.OutputParameters, rpc.ReturnParameter, rpc.Correlation[offset + i]);
                if (outputTiming)
                {
                    DS.ParameterInspectorAfter(inspector.GetType(), sw.Elapsed);
                }

                if (TD.ParameterInspectorAfterCallInvokedIsEnabled())
                {
                    TD.ParameterInspectorAfterCallInvoked(rpc.EventTraceActivity, inspector.GetType().FullName);
                }
            }
        }
Beispiel #4
0
 public void StopImpersonation(ref MessageRpc rpc, IDisposable impersonationContext, IPrincipal originalPrincipal, bool isThreadPrincipalSet)
 {
     try
     {
         if ((this.IsSecurityContextImpersonationRequired(ref rpc) || AspNetEnvironment.Current.RequiresImpersonation) && (impersonationContext != null))
         {
             impersonationContext.Dispose();
         }
         if (isThreadPrincipalSet)
         {
             Thread.CurrentPrincipal = originalPrincipal;
         }
     }
     catch
     {
         string message = null;
         try
         {
             message = System.ServiceModel.SR.GetString("SFxRevertImpersonationFailed0");
         }
         finally
         {
             System.ServiceModel.DiagnosticUtility.FailFast(message);
         }
     }
 }
 void InitializeCallContext(ref MessageRpc rpc)
 {
     if (this.CallContextInitializers.Length > 0)
     {
         InitializeCallContextCore(ref rpc);
     }
 }
Beispiel #6
0
        public void StartImpersonation(ref MessageRpc rpc, out IDisposable impersonationContext, out IPrincipal originalPrincipal, out bool isThreadPrincipalSet)
        {
            ServiceSecurityContext andCacheSecurityContext;

            impersonationContext = null;
            originalPrincipal    = null;
            isThreadPrincipalSet = false;
            bool flag = this.principalPermissionMode != PrincipalPermissionMode.None;
            bool isSecurityContextImpersonationOn = this.IsSecurityContextImpersonationRequired(ref rpc);

            if (flag || isSecurityContextImpersonationOn)
            {
                andCacheSecurityContext = this.GetAndCacheSecurityContext(ref rpc);
            }
            else
            {
                andCacheSecurityContext = null;
            }
            if (flag && (andCacheSecurityContext != null))
            {
                originalPrincipal = this.SetCurrentThreadPrincipal(andCacheSecurityContext, out isThreadPrincipalSet);
            }
            if (isSecurityContextImpersonationOn || AspNetEnvironment.Current.RequiresImpersonation)
            {
                impersonationContext = this.StartImpersonation2(ref rpc, andCacheSecurityContext, isSecurityContextImpersonationOn);
            }
        }
        ServiceSecurityContext GetAndCacheSecurityContext(ref MessageRpc rpc)
        {
            ServiceSecurityContext securityContext = rpc.SecurityContext;

            if (!rpc.HasSecurityContext)
            {
                SecurityMessageProperty securityContextProperty = rpc.Request.Properties.Security;
                if (securityContextProperty == null)
                {
                    securityContext = null; // SecurityContext.Anonymous
                }
                else
                {
                    securityContext = securityContextProperty.ServiceSecurityContext;
                    if (securityContext == null)
                    {
                        throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityContextMissing, rpc.Operation.Name)), rpc.Request);
                    }
                }

                rpc.SecurityContext    = securityContext;
                rpc.HasSecurityContext = true;
            }

            return(securityContext);
        }
        public void StopImpersonation(ref MessageRpc rpc, IDisposable impersonationContext, IPrincipal originalPrincipal, bool isThreadPrincipalSet)
        {
            try
            {
                if (IsSecurityContextImpersonationRequired(ref rpc) || AspNetEnvironment.Current.RequiresImpersonation)
                {
                    if (impersonationContext != null)
                    {
                        impersonationContext.Dispose();
                    }
                }

                if (isThreadPrincipalSet)
                {
                    Thread.CurrentPrincipal = originalPrincipal;
                }
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch
            {
                string message = null;
                try
                {
                    message = SR.GetString(SR.SFxRevertImpersonationFailed0);
                }
                finally
                {
                    DiagnosticUtility.FailFast(message);
                }
            }
        }
 private void InspectInputs(ref MessageRpc rpc)
 {
     if (ParameterInspectors.Length > 0)
     {
         InspectInputsCore(ref rpc);
     }
 }
Beispiel #10
0
 private void UninitializeCallContext(ref MessageRpc rpc)
 {
     if (this.CallContextInitializers.Length > 0)
     {
         this.UninitializeCallContextCore(ref rpc);
     }
 }
 internal void InitializeCallContext(ref MessageRpc rpc)
 {
     if (rpc.Operation.TransactionRequired)
     {
         rpc.Transaction.ThreadEnter(ref rpc.Error);
     }
 }
 internal void ClearCallContext(ref MessageRpc rpc)
 {
     if (rpc.Operation.TransactionRequired)
     {
         rpc.Transaction.ThreadLeave();
     }
 }
        // ........................................................................................................

        internal void SetCurrent(ref MessageRpc rpc)
        {
            Transaction requestTransaction = rpc.Transaction.Current;

            if (!(requestTransaction != null))
            {
                // tx processing requires failfast when state is inconsistent
                DiagnosticUtility.FailFast("we should never get here with a requestTransaction null");
            }

            lock (this.mutex)
            {
                if (this.current == null)
                {
                    this.current = requestTransaction;
                }
                else if (this.current != requestTransaction)
                {
                    this.waiting = requestTransaction;
                    this.paused  = rpc.Pause();
                }
                else
                {
                    rpc.Transaction.Current = this.current; //rpc.Transaction.Current should get the dependent clone
                }
            }
        }
 internal void SetCurrent(ref MessageRpc rpc)
 {
     if (!this.isConcurrent)
     {
         rpc.InstanceContext.Transaction.SetCurrent(ref rpc);
     }
 }
 internal void InitializeCallContext(ref MessageRpc rpc)
 {
     if (rpc.Operation.TransactionRequired)
     {
         rpc.Transaction.ThreadEnter(ref rpc.Error);
     }
 }
Beispiel #16
0
 private void InspectOutputs(ref MessageRpc rpc)
 {
     if (this.ParameterInspectors.Length > 0)
     {
         this.InspectOutputsCore(ref rpc);
     }
 }
 internal void ClearCallContext(ref MessageRpc rpc)
 {
     if (rpc.Operation.TransactionRequired)
     {
         rpc.Transaction.ThreadLeave();
     }
 }
 internal void AddReference(ref MessageRpc rpc, Transaction tx, bool updateCallCount)
 {
     lock (this.mutex)
     {
         if (this.pending == null)
         {
             this.pending = new Dictionary<Transaction, RemoveReferenceRM>();
         }
         if (tx != null)
         {
             RemoveReferenceRM erm;
             if (this.pending == null)
             {
                 this.pending = new Dictionary<Transaction, RemoveReferenceRM>();
             }
             if (!this.pending.TryGetValue(tx, out erm))
             {
                 RemoveReferenceRM erm2 = new RemoveReferenceRM(this.instanceContext, tx, rpc.Operation.Name) {
                     CallCount = 1L
                 };
                 this.pending.Add(tx, erm2);
             }
             else if (updateCallCount)
             {
                 erm.CallCount += 1L;
             }
         }
     }
 }
Beispiel #19
0
        private void InitializeCallContextCore(ref MessageRpc rpc)
        {
            IClientChannel proxy = rpc.Channel.Proxy as IClientChannel;
            int            callContextCorrelationOffset = this.Parent.CallContextCorrelationOffset;

            try
            {
                for (int i = 0; i < rpc.Operation.CallContextInitializers.Length; i++)
                {
                    rpc.Correlation[callContextCorrelationOffset + i] = this.CallContextInitializers[i].BeforeInvoke(rpc.InstanceContext, proxy, rpc.Request);
                }
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }
                if (ErrorBehavior.ShouldRethrowExceptionAsIs(exception))
                {
                    throw;
                }
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
            }
        }
        private void ProcessMessage8(ref MessageRpc rpc)
        {
            rpc.NextProcessor = _processMessage9;

            try
            {
                _error.ProvideMessageFault(ref rpc);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                _error.HandleError(e);
            }

            this.PrepareReply(ref rpc);

            if (rpc.CanSendReply)
            {
                rpc.ReplyTimeoutHelper = new TimeoutHelper(rpc.Channel.OperationTimeout);
            }

            if (!rpc.IsPaused)
            {
                this.ProcessMessage9(ref rpc);
            }
        }
        private void ProcessMessage9(ref MessageRpc rpc)
        {
            rpc.NextProcessor = _processMessageCleanup;

            if (rpc.CanSendReply)
            {
                if (rpc.Reply != null)
                {
                    TraceUtility.MessageFlowAtMessageSent(rpc.Reply, rpc.EventTraceActivity);
                }

                if (_sendAsynchronously)
                {
                    this.BeginReply(ref rpc);
                }
                else
                {
                    this.Reply(ref rpc);
                }
            }

            if (!rpc.IsPaused)
            {
                this.ProcessMessageCleanup(ref rpc);
            }
        }
        private bool PrepareAndAddressReply(ref MessageRpc rpc)
        {
            bool canSendReply = true;

            if (!_manualAddressing)
            {
                if (!object.ReferenceEquals(rpc.RequestID, null))
                {
                    System.ServiceModel.Channels.RequestReplyCorrelator.PrepareReply(rpc.Reply, rpc.RequestID);
                }

                if (!rpc.Channel.HasSession)
                {
                    canSendReply = System.ServiceModel.Channels.RequestReplyCorrelator.AddressReply(rpc.Reply, rpc.ReplyToInfo);
                }
            }

            AddMessageProperties(rpc.Reply, rpc.OperationContext, rpc.Channel);
            if (FxTrace.Trace.IsEnd2EndActivityTracingEnabled && rpc.EventTraceActivity != null)
            {
                rpc.Reply.Properties[EventTraceActivity.Name] = rpc.EventTraceActivity;
            }

            return(canSendReply);
        }
        private bool EndReply(ref MessageRpc rpc)
        {
            bool success = false;

            try
            {
                rpc.RequestContext.EndReply(rpc.AsyncResult);
                rpc.RequestContextThrewOnReply = false;
                success = true;

                if (WcfEventSource.Instance.DispatchMessageStopIsEnabled())
                {
                    WcfEventSource.Instance.DispatchMessageStop(rpc.EventTraceActivity);
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                _error.HandleError(e);
            }

            return(success);
        }
 internal void AfterReply(ref MessageRpc rpc)
 {
     if (rpc.Operation.IsTerminating && rpc.Channel.HasSession)
     {
         var timer = new Timer(s_abortChannelTimerCallback, rpc.Channel.Binder.Channel, rpc.Channel.CloseTimeout, TimeSpan.FromMilliseconds(-1));
     }
 }
Beispiel #25
0
 internal void AfterReply(ref MessageRpc rpc)
 {
     if (rpc.Operation.IsTerminating && rpc.Channel.HasSession)
     {
         new IOThreadTimer(new Action <object>(TerminatingOperationBehavior.AbortChannel), rpc.Channel.Binder.Channel, false).Set(rpc.Channel.CloseTimeout);
     }
 }
        // ........................................................................................................

        internal void AddReference(ref MessageRpc rpc, Transaction tx, bool updateCallCount)
        {
            lock (this.mutex)
            {
                if (this.pending == null)
                {
                    this.pending = new Dictionary <Transaction, RemoveReferenceRM>();
                }

                if (tx != null)
                {
                    if (this.pending == null)
                    {
                        this.pending = new Dictionary <Transaction, RemoveReferenceRM>();
                    }

                    RemoveReferenceRM rm;
                    if (!this.pending.TryGetValue(tx, out rm))
                    {
                        RemoveReferenceRM rrm = new RemoveReferenceRM(this.instanceContext, tx, rpc.Operation.Name);
                        rrm.CallCount = 1;
                        this.pending.Add(tx, rrm);
                    }
                    else if (updateCallCount)
                    {
                        rm.CallCount += 1;
                    }
                }
            }
        }
Beispiel #27
0
 internal void UnlockInstance(ref MessageRpc rpc)
 {
     if (_concurrencyMode != ConcurrencyMode.Multiple)
     {
         ConcurrencyBehavior.UnlockInstance(rpc.InstanceContext);
     }
 }
 public static void CreateIfRequired(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc messageRpc)
 {
     if (messageRpc.Operation.ReceiveContextAcknowledgementMode != ReceiveContextAcknowledgementMode.ManualAcknowledgement)
     {
         ReceiveContext property = null;
         if (!ReceiveContext.TryGet(messageRpc.Request, out property))
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("SFxReceiveContextPropertyMissing", new object[] { typeof(ReceiveContext).Name })));
         }
         messageRpc.Request.Properties.Remove(ReceiveContext.Name);
         if ((messageRpc.Operation.ReceiveContextAcknowledgementMode == ReceiveContextAcknowledgementMode.AutoAcknowledgeOnReceive) && !messageRpc.Operation.TransactionRequired)
         {
             AcknowledgementCompleteCallbackState state = new AcknowledgementCompleteCallbackState {
                 DispatchRuntime = dispatchRuntime,
                 Rpc = messageRpc
             };
             IAsyncResult result = new AcknowledgementCompleteAsyncResult(property, TimeSpan.MaxValue, ref messageRpc, null, handleEndComplete, state);
             if (result.CompletedSynchronously)
             {
                 AcknowledgementCompleteAsyncResult.End(result);
             }
         }
         else
         {
             messageRpc.ReceiveContext = new ReceiveContextRPCFacet(property);
         }
     }
 }
 internal void HandleError(ref MessageRpc rpc)
 {
     if (rpc.Error != null)
     {
         this.HandleErrorCore(ref rpc);
     }
 }
 private void HandleErrorCore(ref MessageRpc rpc)
 {
     if (this.HandleErrorCommon(rpc.Error, ref rpc.FaultInfo))
     {
         rpc.Error = null;
     }
 }
 internal void AfterReply(ref MessageRpc rpc)
 {
     if (rpc.Operation.IsTerminating && rpc.Channel.HasSession)
     {
         new IOThreadTimer(new Action<object>(TerminatingOperationBehavior.AbortChannel), rpc.Channel.Binder.Channel, false).Set(rpc.Channel.CloseTimeout);
     }
 }
 internal void ProvideMessageFault(ref MessageRpc rpc)
 {
     if (rpc.Error != null)
     {
         this.ProvideMessageFaultCore(ref rpc);
     }
 }
 private void HandleErrorCore(ref MessageRpc rpc)
 {
     if (this.HandleErrorCommon(rpc.Error, ref rpc.FaultInfo))
     {
         rpc.Error = null;
     }
 }
 internal void ProvideMessageFault(ref MessageRpc rpc)
 {
     if (rpc.Error != null)
     {
         ProvideMessageFaultCore(ref rpc);
     }
 }
 internal void HandleError(ref MessageRpc rpc)
 {
     if (rpc.Error != null)
     {
         this.HandleErrorCore(ref rpc);
     }
 }
Beispiel #36
0
 void BeforeSendReply(ref MessageRpc rpc, ref Exception exception, ref bool thereIsAnUnhandledException)
 {
     if (_messageInspectors.Length > 0)
     {
         BeforeSendReplyCore(ref rpc, ref exception, ref thereIsAnUnhandledException);
     }
 }
Beispiel #37
0
 internal void UnlockInstance(ref MessageRpc rpc)
 {
     if (this.mode != ConcurrencyMode.Multiple)
     {
         UnlockInstance(rpc.InstanceContext);
     }
 }
            internal Wrapper(ref MessageRpc rpc)
            {
                this.rpc = rpc;
                MessageRpcProcessor nextProcessor = rpc.NextProcessor;

                this.rpc.IncrementBusyCount();
            }
        void ProvideMessageFaultCoreCoda(ref MessageRpc rpc)
        {
            if (rpc.FaultInfo.Fault.Headers.Action == null)
            {
                rpc.FaultInfo.Fault.Headers.Action = rpc.RequestVersion.Addressing.DefaultFaultAction;
            }

            rpc.Reply = rpc.FaultInfo.Fault;
        }
 public void Complete(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc rpc, TimeSpan timeout, Transaction transaction)
 {
     AcknowledgementCompleteCallbackState state = new AcknowledgementCompleteCallbackState {
         DispatchRuntime = dispatchRuntime,
         Rpc = rpc
     };
     IAsyncResult result = new AcknowledgementCompleteAsyncResult(this.receiveContext, timeout, ref rpc, transaction, handleEndComplete, state);
     if (result.CompletedSynchronously)
     {
         AcknowledgementCompleteAsyncResult.End(result);
     }
 }
        void ProvideMessageFaultCore(ref MessageRpc rpc)
        {
            if (this.messageVersion != rpc.RequestVersion)
            {
                Fx.Assert("System.ServiceModel.Dispatcher.ErrorBehavior.ProvideMessageFaultCore(): (this.messageVersion != rpc.RequestVersion)");
            }

            this.InitializeFault(ref rpc);

            this.ProvideFault(rpc.Error, rpc.Channel.GetProperty<FaultConverter>(), ref rpc.FaultInfo);

            this.ProvideMessageFaultCoreCoda(ref rpc);
        }
 void InitializeFault(ref MessageRpc rpc)
 {
     Exception error = rpc.Error;
     FaultException fault = error as FaultException;
     if (fault != null)
     {
         string action;
         MessageFault messageFault = rpc.Operation.FaultFormatter.Serialize(fault, out action);
         if (action == null)
             action = rpc.RequestVersion.Addressing.DefaultFaultAction;
         if (messageFault != null)
             rpc.FaultInfo.Fault = Message.CreateMessage(rpc.RequestVersion, messageFault, action);
     }
 }
 internal void AfterReply(ref MessageRpc rpc, ErrorBehavior error)
 {
     InstanceContext instanceContext = rpc.InstanceContext;
     if (instanceContext != null)
     {
         try
         {
             if (rpc.Operation.ReleaseInstanceAfterCall)
             {
                 if (instanceContext.State == CommunicationState.Opened)
                 {
                     instanceContext.ReleaseServiceInstance();
                 }
             }
             else if (((this.releaseServiceInstanceOnTransactionComplete && this.isSynchronized) && (rpc.transaction != null)) && (rpc.transaction.IsCompleted || (rpc.Error != null)))
             {
                 if (instanceContext.State == CommunicationState.Opened)
                 {
                     instanceContext.ReleaseServiceInstance();
                 }
                 if (DiagnosticUtility.ShouldTraceInformation)
                 {
                     TraceUtility.TraceEvent(TraceEventType.Information, 0xe000c, System.ServiceModel.SR.GetString("TraceCodeTxReleaseServiceInstanceOnCompletion", new object[] { "*" }));
                 }
             }
         }
         catch (Exception exception)
         {
             if (Fx.IsFatal(exception))
             {
                 throw;
             }
             error.HandleError(exception);
         }
         try
         {
             instanceContext.UnbindRpc(ref rpc);
         }
         catch (Exception exception2)
         {
             if (Fx.IsFatal(exception2))
             {
                 throw;
             }
             error.HandleError(exception2);
         }
     }
 }
        //Called from ProcessMessage1
        //ManualAcknowledgementMode : No-Op.
        //Non-transacted V1 Operation : Remove RC; RC.Complete;(Will pause RPC if truly async)
        //Else : Create and Attach RCFacet to MessageRPC.
        public static void CreateIfRequired(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc messageRpc)
        {
            if (messageRpc.Operation.ReceiveContextAcknowledgementMode == ReceiveContextAcknowledgementMode.ManualAcknowledgement)
            {
                //Manual mode, user owns the acknowledgement.
                return;
            }

            //Retrieve RC from request and ensure it is removed from Message.
            ReceiveContext receiveContext = null;
            if (!ReceiveContext.TryGet(messageRpc.Request, out receiveContext))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(
                    SR.GetString(SR.SFxReceiveContextPropertyMissing,
                    typeof(ReceiveContext).Name)));
            }
            messageRpc.Request.Properties.Remove(ReceiveContext.Name);

            if (messageRpc.Operation.ReceiveContextAcknowledgementMode == ReceiveContextAcknowledgementMode.AutoAcknowledgeOnReceive)
            {
                if (!messageRpc.Operation.TransactionRequired)
                {
                    //Attempt to complete the ReceiveContext.
                    //Async Result Ensures RPC is paused if it goes ASYNC.
                    IAsyncResult result = new AcknowledgementCompleteAsyncResult(
                        receiveContext,
                        TimeSpan.MaxValue,
                        ref messageRpc,
                        null,
                        handleEndComplete,
                        new AcknowledgementCompleteCallbackState
                        {
                            DispatchRuntime = dispatchRuntime,
                            Rpc = messageRpc
                        });

                    if (result.CompletedSynchronously)
                    {
                        AcknowledgementCompleteAsyncResult.End(result);
                    }
                    return;
                }
            }
            //We have to create a Facet for acknowledgement at later stage.
            messageRpc.ReceiveContext = new ReceiveContextRPCFacet(receiveContext);
        }
        internal void AfterReply(ref MessageRpc rpc, ErrorBehavior error)
        {
            InstanceContext context = rpc.InstanceContext;

            if (context != null)
            {
                try
                {
                    context.UnbindRpc(ref rpc);
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }
                    error.HandleError(e);
                }
            }
        }
        //Called from ProcessMessage31.
        //Mode is TransactedOperation && !ManualAcknowledgement
        //Will pause RPC if Complete is truly Async.
        public void Complete(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc rpc, TimeSpan timeout, Transaction transaction)
        {
            Fx.Assert(transaction != null, "Cannot reach here with null transaction");
            //Async Result Ensures the RPC is paused if the request goes Async.
            IAsyncResult result = new AcknowledgementCompleteAsyncResult(
                this.receiveContext,
                timeout,
                ref rpc,
                transaction,
                handleEndComplete,
                new AcknowledgementCompleteCallbackState
                {
                    DispatchRuntime = dispatchRuntime,
                    Rpc = rpc
                });

            if (result.CompletedSynchronously)
            {
                AcknowledgementCompleteAsyncResult.End(result);
            }
        }
        internal void EnsureInstanceContext(ref MessageRpc rpc)
        {
            if (rpc.InstanceContext == null)
            {
                throw new ArgumentNullException("rpc.InstanceContext");
            }

            rpc.OperationContext.SetInstanceContext(rpc.InstanceContext);
            rpc.InstanceContext.Behavior = this;

            if (rpc.InstanceContext.State == CommunicationState.Created)
            {
                lock (rpc.InstanceContext.ThisLock)
                {
                    if (rpc.InstanceContext.State == CommunicationState.Created)
                    {
                        rpc.InstanceContext.Open(rpc.Channel.CloseTimeout);
                    }
                }
            }
            rpc.InstanceContext.BindRpc(ref rpc);
        }
 private void BindCore(ref MessageRpc rpc, bool startOperation)
 {
     SynchronizationContext syncContext = this.GetSyncContext(rpc.InstanceContext);
     if (syncContext != null)
     {
         IResumeMessageRpc state = rpc.Pause();
         if (startOperation)
         {
             syncContext.OperationStarted();
             syncContext.Post(this.ThreadAffinityStartCallbackDelegate, state);
         }
         else
         {
             syncContext.Post(this.ThreadAffinityEndCallbackDelegate, state);
         }
     }
     else if (rpc.SwitchedThreads)
     {
         IResumeMessageRpc rpc3 = rpc.Pause();
         ActionItem.Schedule(CleanThreadCallbackDelegate, rpc3);
     }
 }
 internal void LockInstance(ref MessageRpc rpc)
 {
     if (this.mode != ConcurrencyMode.Multiple)
     {
         ConcurrencyInstanceContextFacet concurrency = rpc.InstanceContext.Concurrency;
         lock (rpc.InstanceContext.ThisLock)
         {
             if (!concurrency.Locked)
             {
                 concurrency.Locked = true;
             }
             else
             {
                 MessageRpcWaiter waiter = new MessageRpcWaiter(rpc.Pause());
                 concurrency.EnqueueNewMessage(waiter);
             }
         }
         if (this.mode == ConcurrencyMode.Reentrant)
         {
             rpc.OperationContext.IsServiceReentrant = true;
         }
     }
 }
 private ServiceSecurityContext GetAndCacheSecurityContext(ref MessageRpc rpc)
 {
     ServiceSecurityContext securityContext = rpc.SecurityContext;
     if (!rpc.HasSecurityContext)
     {
         SecurityMessageProperty security = rpc.Request.Properties.Security;
         if (security == null)
         {
             securityContext = null;
         }
         else
         {
             securityContext = security.ServiceSecurityContext;
             if (securityContext == null)
             {
                 throw TraceUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("SecurityContextMissing", new object[] { rpc.Operation.Name })), rpc.Request);
             }
         }
         rpc.SecurityContext = securityContext;
         rpc.HasSecurityContext = true;
     }
     return securityContext;
 }
        internal void ProcessMessage11(ref MessageRpc rpc)
        {
            rpc.NextProcessor = this.processMessage2;

            if (rpc.Operation.IsOneWay)
            {
                rpc.RequestContext.Reply(null);
                rpc.OperationContext.RequestContext = null;
            }
            else
            {
                if (!rpc.Channel.IsReplyChannel &&
                    ((object)rpc.RequestID == null) &&
                    (rpc.Operation.Action != MessageHeaders.WildcardAction))
                {
                    CommunicationException error = new CommunicationException(SR.GetString(SR.SFxOneWayMessageToTwoWayMethod0));
                    throw TraceUtility.ThrowHelperError(error, rpc.Request);
                }

                if (!this.manualAddressing)
                {
                    EndpointAddress replyTo = rpc.ReplyToInfo.ReplyTo;
                    if (replyTo != null && replyTo.IsNone && rpc.Channel.IsReplyChannel)
                    {
                        CommunicationException error = new CommunicationException(SR.GetString(SR.SFxRequestReplyNone));
                        throw TraceUtility.ThrowHelperError(error, rpc.Request);
                    }

                    if (this.isOnServer)
                    {
                        EndpointAddress remoteAddress = rpc.Channel.RemoteAddress;
                        if ((remoteAddress != null) && !remoteAddress.IsAnonymous)
                        {
                            MessageHeaders headers = rpc.Request.Headers;
                            Uri remoteUri = remoteAddress.Uri;

                            if ((replyTo != null) && !replyTo.IsAnonymous && (remoteUri != replyTo.Uri))
                            {
                                string text = SR.GetString(SR.SFxRequestHasInvalidReplyToOnServer, replyTo.Uri, remoteUri);
                                Exception error = new InvalidOperationException(text);
                                throw TraceUtility.ThrowHelperError(error, rpc.Request);
                            }

                            EndpointAddress faultTo = headers.FaultTo;
                            if ((faultTo != null) && !faultTo.IsAnonymous && (remoteUri != faultTo.Uri))
                            {
                                string text = SR.GetString(SR.SFxRequestHasInvalidFaultToOnServer, faultTo.Uri, remoteUri);
                                Exception error = new InvalidOperationException(text);
                                throw TraceUtility.ThrowHelperError(error, rpc.Request);
                            }

                            if (rpc.RequestVersion.Addressing == AddressingVersion.WSAddressingAugust2004)
                            {
                                EndpointAddress from = headers.From;
                                if ((from != null) && !from.IsAnonymous && (remoteUri != from.Uri))
                                {
                                    string text = SR.GetString(SR.SFxRequestHasInvalidFromOnServer, from.Uri, remoteUri);
                                    Exception error = new InvalidOperationException(text);
                                    throw TraceUtility.ThrowHelperError(error, rpc.Request);
                                }
                            }
                        }
                    }
                }
            }

            if (this.concurrency.IsConcurrent(ref rpc))
            {
                rpc.Channel.IncrementActivity();
                rpc.SuccessfullyIncrementedActivity = true;
            }

            if (this.authenticationBehavior != null)
            {
                this.authenticationBehavior.Authenticate(ref rpc);
            }

            if (this.authorizationBehavior != null)
            {
                this.authorizationBehavior.Authorize(ref rpc);
            }

            this.instance.EnsureInstanceContext(ref rpc);
            this.TransferChannelFromPendingList(ref rpc);

            this.AcquireDynamicInstanceContext(ref rpc);

            if (!rpc.IsPaused)
            {
                this.ProcessMessage2(ref rpc);
            }
        }
        internal void ProcessMessage1(ref MessageRpc rpc)
        {
            rpc.NextProcessor = this.processMessage11;

            if (this.receiveContextEnabledChannel)
            {
                ReceiveContextRPCFacet.CreateIfRequired(this, ref rpc);
            }

            if (!rpc.IsPaused)
            {
                this.ProcessMessage11(ref rpc);
            }
            else if (this.isOnServer && DiagnosticUtility.ShouldTraceInformation && !this.didTraceProcessMessage1)
            {
                this.didTraceProcessMessage1 = true;

                TraceUtility.TraceEvent(
                    TraceEventType.Information,
                    TraceCode.MessageProcessingPaused,
                    SR.GetString(SR.TraceCodeProcessMessage31Paused,
                    rpc.Channel.DispatchRuntime.EndpointDispatcher.ContractName,
                    rpc.Channel.DispatchRuntime.EndpointDispatcher.EndpointAddress));
            }
        }
        bool PrepareAndAddressReply(ref MessageRpc rpc)
        {
            bool canSendReply = true;

            if (!this.manualAddressing)
            {
                if (!object.ReferenceEquals(rpc.RequestID, null))
                {
                    System.ServiceModel.Channels.RequestReplyCorrelator.PrepareReply(rpc.Reply, rpc.RequestID);
                }

                if (!rpc.Channel.HasSession)
                {
                    canSendReply = System.ServiceModel.Channels.RequestReplyCorrelator.AddressReply(rpc.Reply, rpc.ReplyToInfo);
                }
            }

            AddMessageProperties(rpc.Reply, rpc.OperationContext, rpc.Channel);
            if (FxTrace.Trace.IsEnd2EndActivityTracingEnabled && rpc.EventTraceActivity != null)
            {
                rpc.Reply.Properties[EventTraceActivity.Name] = rpc.EventTraceActivity;
            }

            return canSendReply;
        }
        void PrepareReply(ref MessageRpc rpc)
        {
            RequestContext context = rpc.OperationContext.RequestContext;
            Exception exception = null;
            bool thereIsAnUnhandledException = false;

            if (!rpc.Operation.IsOneWay)
            {
                if (DiagnosticUtility.ShouldTraceWarning)
                {
                    // If a service both returns null and sets RequestContext null, that
                    // means they handled it (either by calling Close or Reply manually).
                    // These traces catch accidents, where you accidentally return null,
                    // or you accidentally close the context so we can't return your message.
                    if ((rpc.Reply == null) && (context != null))
                    {
                        TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Warning,
                            TraceCode.ServiceOperationMissingReply,
                            SR.GetString(SR.TraceCodeServiceOperationMissingReply, rpc.Operation.Name ?? String.Empty),
                            null, null);
                    }
                    else if ((context == null) && (rpc.Reply != null))
                    {
                        TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Warning,
                            TraceCode.ServiceOperationMissingReplyContext,
                            SR.GetString(SR.TraceCodeServiceOperationMissingReplyContext, rpc.Operation.Name ?? String.Empty),
                            null, null);
                    }
                }

                if ((context != null) && (rpc.Reply != null))
                {
                    try
                    {
                        rpc.CanSendReply = PrepareAndAddressReply(ref rpc);
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }
                        thereIsAnUnhandledException = (!this.error.HandleError(e)) || thereIsAnUnhandledException;
                        exception = e;
                    }
                }
            }

            this.BeforeSendReply(ref rpc, ref exception, ref thereIsAnUnhandledException);

            if (rpc.Operation.IsOneWay)
            {
                rpc.CanSendReply = false;
            }

            if (!rpc.Operation.IsOneWay && (context != null) && (rpc.Reply != null))
            {
                if (exception != null)
                {
                    // We don't call ProvideFault again, since we have already passed the
                    // point where SFx addresses the reply, and it is reasonable for
                    // ProvideFault to expect that SFx will address the reply.  Instead
                    // we always just do 'internal server error' processing.
                    rpc.Error = exception;
                    this.error.ProvideOnlyFaultOfLastResort(ref rpc);

                    try
                    {
                        rpc.CanSendReply = PrepareAndAddressReply(ref rpc);
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }
                        this.error.HandleError(e);
                    }
                }
            }
            else if ((exception != null) && thereIsAnUnhandledException)
            {
                rpc.Abort();
            }
        }
 internal bool IsConcurrent(ref MessageRpc rpc)
 {
     return this.concurrency.IsConcurrent(ref rpc);
 }
        bool EndReply(ref MessageRpc rpc)
        {
            bool success = false;

            try
            {
                rpc.RequestContext.EndReply(rpc.AsyncResult);
                rpc.RequestContextThrewOnReply = false;
                success = true;

                if (TD.DispatchMessageStopIsEnabled())
                {
                    TD.DispatchMessageStop(rpc.EventTraceActivity);
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                this.error.HandleError(e);
            }

            return success;
        }
 internal bool Dispatch(ref MessageRpc rpc, bool isOperationContextSet)
 {
     rpc.ErrorProcessor = this.processMessage8;
     rpc.NextProcessor = this.processMessage1;
     return rpc.Process(isOperationContextSet);
 }
        void ProcessMessage2(ref MessageRpc rpc)
        {
            rpc.NextProcessor = this.processMessage3;

            this.AfterReceiveRequest(ref rpc);

            if (!this.ignoreTransactionFlow)
            {
                // Transactions need to have the context in the message
                rpc.TransactionMessageProperty = TransactionMessageProperty.TryGet(rpc.Request);
            }

            this.concurrency.LockInstance(ref rpc);

            if (!rpc.IsPaused)
            {
                this.ProcessMessage3(ref rpc);
            }
            else if (this.isOnServer && DiagnosticUtility.ShouldTraceInformation && !this.didTraceProcessMessage2)
            {
                this.didTraceProcessMessage2 = true;

                TraceUtility.TraceEvent(
                    TraceEventType.Information,
                    TraceCode.MessageProcessingPaused,
                    SR.GetString(SR.TraceCodeProcessMessage2Paused,
                    rpc.Channel.DispatchRuntime.EndpointDispatcher.ContractName,
                    rpc.Channel.DispatchRuntime.EndpointDispatcher.EndpointAddress));
            }
        }
        void ProcessMessage3(ref MessageRpc rpc)
        {
            rpc.NextProcessor = this.processMessage31;

            rpc.SuccessfullyLockedInstance = true;

            // This also needs to happen after LockInstance, in case
            // we are using an AutoComplete=false transaction.
            if (this.transaction != null)
            {
                this.transaction.ResolveTransaction(ref rpc);
                if (rpc.Operation.TransactionRequired)
                {
                    this.transaction.SetCurrent(ref rpc);
                }
            }

            if (!rpc.IsPaused)
            {
                this.ProcessMessage31(ref rpc);
            }
            else if (this.isOnServer && DiagnosticUtility.ShouldTraceInformation && !this.didTraceProcessMessage3)
            {
                this.didTraceProcessMessage3 = true;

                TraceUtility.TraceEvent(
                    TraceEventType.Information,
                    TraceCode.MessageProcessingPaused,
                    SR.GetString(SR.TraceCodeProcessMessage3Paused,
                    rpc.Channel.DispatchRuntime.EndpointDispatcher.ContractName,
                    rpc.Channel.DispatchRuntime.EndpointDispatcher.EndpointAddress));
            }
        }
        void EndFinalizeCorrelation(ref MessageRpc rpc)
        {
            try
            {
                rpc.Reply = rpc.CorrelationCallback.EndFinalizeCorrelation(rpc.AsyncResult);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                if (!this.error.HandleError(e))
                {
                    rpc.CanSendReply = false;
                }
            }
        }