File: System\ServiceModel\Security\ImpersonatingMessage.cs
Project: ndp\cdf\src\WCF\ServiceModel\System.ServiceModel.csproj (System.ServiceModel)
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Security
{
    using System.Security.Principal;
    using System.ServiceModel.Channels;
    using System.Xml;
 
    sealed class ImpersonatingMessage : Message
    {
        Message innerMessage;
 
        public ImpersonatingMessage(Message innerMessage)
        {
            if (innerMessage == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerMessage");
            }
            this.innerMessage = innerMessage;
        }
 
        public override bool IsEmpty
        {
            get
            {
                return this.innerMessage.IsEmpty;
            }
        }
 
        public override bool IsFault
        {
            get { return this.innerMessage.IsFault; }
        }
 
        public override MessageHeaders Headers
        {
            get { return this.innerMessage.Headers; }
        }
 
        public override MessageProperties Properties
        {
            get { return this.innerMessage.Properties; }
        }
 
        public override MessageVersion Version
        {
            get { return this.innerMessage.Version; }
        }
 
        internal override RecycledMessageState RecycledMessageState
        {
            get
            {
                return this.innerMessage.RecycledMessageState;
            }
        }
 
        protected override void OnClose()
        {
            base.OnClose();
            this.innerMessage.Close();
        }
 
        //Runs impersonated.
        protected override IAsyncResult OnBeginWriteMessage(XmlDictionaryWriter writer, AsyncCallback callback, object state)
        {
            ImpersonateOnSerializingReplyMessageProperty impersonationProperty = null;
            IDisposable impersonationContext = null;
            IPrincipal originalPrincipal = null;
            bool isThreadPrincipalSet = false;
 
            if (!ImpersonateOnSerializingReplyMessageProperty.TryGet(this.innerMessage, out impersonationProperty))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToImpersonateWhileSerializingReponse)));
            }
 
            try
            {
                impersonationProperty.StartImpersonation(out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
                return this.innerMessage.BeginWriteMessage(writer, callback, state);
            }
            finally
            {
                try
                {
                    impersonationProperty.StopImpersonation(impersonationContext, originalPrincipal, isThreadPrincipalSet);
                }
#pragma warning suppress 56500 // covered by FxCOP
                catch
                {
                    string message = null;
                    try
                    {
                        message = SR.GetString(SR.SFxRevertImpersonationFailed0);
                    }
                    finally
                    {
                        DiagnosticUtility.FailFast(message);
                    }
                }
            }
        }
 
        //Runs impersonated.
        protected override void OnWriteMessage(XmlDictionaryWriter writer)
        {
            this.ImpersonateCall(() => this.innerMessage.WriteMessage(writer));
        }
     
        protected override void OnEndWriteMessage(IAsyncResult result)
        {
            this.innerMessage.EndWriteMessage(result);
        }
 
        protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
        {
            this.innerMessage.WriteStartEnvelope(writer);
        }
 
        protected override void OnWriteStartHeaders(XmlDictionaryWriter writer)
        {
            this.innerMessage.WriteStartHeaders(writer);
        }
 
        protected override void OnWriteStartBody(XmlDictionaryWriter writer)
        {
            this.innerMessage.WriteStartBody(writer);
        }
 
        protected override string OnGetBodyAttribute(string localName, string ns)
        {
            return this.innerMessage.GetBodyAttribute(localName, ns);
        }
 
        protected override MessageBuffer OnCreateBufferedCopy(int maxBufferSize)
        {
            return this.innerMessage.CreateBufferedCopy(maxBufferSize);
        }
      
        protected override IAsyncResult OnBeginWriteBodyContents(XmlDictionaryWriter writer, AsyncCallback callback, object state)
        {
            ImpersonateOnSerializingReplyMessageProperty impersonationProperty = null;
            IDisposable impersonationContext = null;
            IPrincipal originalPrincipal = null;
            bool isThreadPrincipalSet = false;
 
            if (!ImpersonateOnSerializingReplyMessageProperty.TryGet(this.innerMessage, out impersonationProperty))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToImpersonateWhileSerializingReponse)));
            }
 
            try
            {
                impersonationProperty.StartImpersonation(out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
                return this.innerMessage.BeginWriteBodyContents(writer, callback, state);
            }
            finally
            {
                try
                {
                    impersonationProperty.StopImpersonation(impersonationContext, originalPrincipal, isThreadPrincipalSet);
                }
#pragma warning suppress 56500 // covered by FxCOP
                catch
                {
                    string message = null;
                    try
                    {
                        message = SR.GetString(SR.SFxRevertImpersonationFailed0);
                    }
                    finally
                    {
                        DiagnosticUtility.FailFast(message);
                    }
                }
            }
            
           
        }
 
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
          this.ImpersonateCall( () => this.innerMessage.WriteBodyContents(writer));
        }
 
        protected override void OnEndWriteBodyContents(IAsyncResult result)
        {
            this.innerMessage.EndWriteBodyContents(result);
        }
 
        //Runs impersonated.
        protected override void OnBodyToString(XmlDictionaryWriter writer)
        {
            this.ImpersonateCall(() => this.innerMessage.BodyToString(writer));
        }
 
        void ImpersonateCall(Action callToImpersonate)
        {
            ImpersonateOnSerializingReplyMessageProperty impersonationProperty = null;
            IDisposable impersonationContext = null;
            IPrincipal originalPrincipal = null;
            bool isThreadPrincipalSet = false;
 
            if (!ImpersonateOnSerializingReplyMessageProperty.TryGet(this.innerMessage, out impersonationProperty))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToImpersonateWhileSerializingReponse)));
            }
 
            try
            {
                impersonationProperty.StartImpersonation(out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
                callToImpersonate();
            }
            finally
            {
                try
                {
                    impersonationProperty.StopImpersonation(impersonationContext, originalPrincipal, isThreadPrincipalSet);
                }
#pragma warning suppress 56500 // covered by FxCOP
                catch
                {
                    string message = null;
                    try
                    {
                        message = SR.GetString(SR.SFxRevertImpersonationFailed0);
                    }
                    finally
                    {
                        DiagnosticUtility.FailFast(message);
                    }
                }
            }
        }
    }
}