Request.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / Request.cs / 1 / Request.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
//
// Presharp uses the c# pragma mechanism to supress its warnings. 
// These are not recognised by the base compiler so we need to explictly
// disable the following warnings. See http://winweb/cse/Tools/PREsharp/userguide/default.asp 
// for details. 
//
#pragma warning disable 1634, 1691      // unknown message, unknown pragma 



namespace Microsoft.InfoCards 
{
    using Microsoft.Win32.SafeHandles; 
    using System; 
    using System.Collections.Generic;
    using System.ComponentModel; 
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Principal; 
    using System.IO;
    using Microsoft.InfoCards.Diagnostics; 
    using IDT=Microsoft.InfoCards.Diagnostics.InfoCardTrace; 
    using System.Net;
 

    //
    // Summary
    // The base class for all incoming 
    // RpcRequests. Stores information common to all requests
    // and enforces control flow (see DoProcessRequest). 
    // 
    internal abstract class Request : IDisposable
    { 
        class RequestHandleDictionary : HandleDictionary< Request > {}

        //
        // This maps a handle to a request. 
        // This is to enable support for simultaneous requests so that
        // child UI agent requests can find their parent request 
        // 
        static RequestHandleDictionary s_existingClientRequests = new RequestHandleDictionary();
 
        static ExceptionTranslationTable s_exceptionToHResultTable = ExceptionTranslationTable.Instance;

        //
        // Pointer to inargs and outargs to request 
        //
        Stream m_inArgs; 
        Stream m_outArgs; 

        // 
        // A unique id for this instance.
        //
        int m_requestHandle = 0;
 
        //
        // For generating the random number for each requests 
        // 
        static object s_syncRoot = new Object();
 
        //
        // For reading the proxy data for the user making the request
        //
        IWebProxy m_proxy = null; 

        // 
        // To synchronize Add & Remove AsyncResult 
        //
        object m_syncRoot; 

        //
        // The RpcHandle thru which this call came thru
        // 
        IntPtr m_rpcHandle;
 
        // 
        // A placeholder for any exceptions that are thrown whilst this
        // request is being processed 
        //
        Exception m_processingException;

        // 
        // The set of Exceptions that are ok to handle automatically.  Exceptions derived from InfoCard
        // exception are always handled automatically. 
        // 
        ExceptionList m_recoverableExceptions;
 
        WindowsImpersonationContext  m_impersonationContext;

        int m_initHResult;  // Holds the HResult from any exception thrown during initialization.
        string m_extendedErrorMessage;  // Holds the extended error message received from an IP/STS 

 
        int m_lcid = -1; // LCID for the user language 
        //
        // Summary 
        // Constructor's main task is to call InsertThisRequestIntoDictionary
        // apart from initializing class variables
        //
        protected Request( IntPtr rpcHandle, Stream inArgs, Stream outArgs, ExceptionList recoverableExceptions ) 
        {
            m_inArgs = inArgs; 
            m_outArgs = outArgs; 
            m_rpcHandle = rpcHandle;
            m_recoverableExceptions = recoverableExceptions; 
            m_syncRoot = new Object();
            m_initHResult = 0;
            InsertThisRequestIntoDictionary();
        } 

        // 
        // Summary 
        // Returns exceptions that are thrown whilst this
        // request is being processed 
        //
        public Exception ProcessingException
        {
            get 
            {
                return m_processingException; 
            } 
            set
            { 
                m_processingException = value;
            }
        }
 
        //
        // Summary 
        //  Return the WebProxy for the user 
        //
        public IWebProxy UserProxy 
        {
            get
            {
                if( null == m_proxy ) 
                {
                    m_proxy = WebRequest.GetSystemWebProxy(); 
                } 
                return m_proxy;
            } 
        }


        // 
        // Summary
        // Set and returns the language associated with the user of this instance of the request 
        // 
        public int UserLanguage
        { 
            get
            {
                IDT.Assert( m_lcid >= 0, " The user language has not been set in the service" );
                return m_lcid; 
            }
            set 
            { 
                m_lcid = value;
            } 
        }

        //
        // Summary 
        // Specifies the stream where input information pertaining to this request can be read from.
        // 
        protected Stream InArgs 
        {
            get { return m_inArgs; } 
        }

        //
        // Summary 
        // Specifies the stream where output information from this request would be
        // returned to. 
        // 
        public Stream OutArgs
        { 
            get { return m_outArgs; }
        }

        // 
        // Summary
        // Used by ClientRequestto synchronize adding and removing results 
        // 
        protected object SyncRoot
        { 
            get { return m_syncRoot; }
        }

        // 
        // Summary
        // Returns the rpcHandle associated with this request 
        // 
        protected IntPtr RpcHandle
        { 
            get { return m_rpcHandle; }
        }

 
        //
        // Summary 
        // Returns an unique id for this instance. 
        //
        public int RequestHandle 
        {
            get { return m_requestHandle; }
        }
 

        public abstract WindowsIdentity RequestorIdentity 
        { 
            get;
        } 


        internal void Initialize()
        { 
            try
            { 
                // 
                // Allow initialization before impersonating the user.
                // 
                OnInitializeAsSystem();

                //
                // Imerpersonate the original requestor. 
                //
                ImpersonateRequestor(); 
 
                //
                // Allow initialization as the user. 
                //
                OnInitializeAsUser();
            }
            #pragma warning suppress 56500  // do not catch all exceptions. System handles this in HandleException method. 
            catch( Exception e )
            { 
                m_initHResult = HandleException( e, true ); 
            }
        } 



 
        void ImpersonateRequestor()
        { 
            IDT.Assert( null != RequestorIdentity, "RequestorIdentity can not be null, the derived class  should have populated this on initialize" ); 

 
            //
            // Check to see if the incoming client who made the request is LSA, if so, throw.
            //
            if( RequestorIdentity.IsSystem ) 
            {
                throw IDT.ThrowHelperError( new CommunicationException( 
                                                        SR.GetString( SR.UserIdentityEqualSystemNotSupported ) ) ); 
            }
 
            m_impersonationContext = RequestorIdentity.Impersonate();

        }
 
        //
        // Summary: 
        //  Translates non InfoCard exceptions to HResults. 
        //
        // Parameters: 
        //  e  - the exceptions to translate.
        //
        private int GetHResultFromException( Exception e )
        { 
            int status = 0;
            Type exceptionType = e.GetType(); 
 
            //
            // See if the exception is in our standard table. 
            //
            if ( s_exceptionToHResultTable.ContainsKey( exceptionType ) )
            {
                status = s_exceptionToHResultTable[ exceptionType ]; 
            }
            else if( e is Win32Exception ) 
            { 
                //
                // There isn't a single translation for Win32Exceptions. 
                //
                status = ( ( Win32Exception )e ).NativeErrorCode;
            }
            else 
            {
                // 
                // We don't have a translation for this exception.  It must not have really been expected or 
                // recoverable.
                // 
                InfoCardService.Crash( e );
            }

            return status; 
        }
 
        protected int HandleException( Exception e ) 
        {
            return HandleException( e, false ); 
        }

        //
        // Summary 
        // Calls virtual OnHandleException so that base classes are able to
        // implement their own request specific exception handling. 
        // 
        // Parameters
        // e                - The exception to handle. 
        // isInitializing   - Indicates whether the exception was thrown during initialization.  If so, then
        //                    we shouldn't call OnHandleExceptions because the request probably isn't fully
        //                    initialized and may not be able to handle the call.
        // 
        protected int HandleException( Exception e, bool isInitializing )
        { 
            int errorCode = 0; 
            Exception exceptionToTest;
 
            if( IDT.IsFatal( e ) )
            {
                IDT.TraceAndLogException( e );
                InfoCardService.Crash( e ); 
            }
            // 
            // If we have recieved the wrapper exception of InfoCardRequestException, 
            //      pull out the inner exception and deal with that.
            // 
            if ( e is InfoCardRequestException )
            {
                exceptionToTest = e.InnerException;
            } 
            else
            { 
                exceptionToTest = e; 
            }
 
            IDT.TraceDebug( e.ToString() );
            if ( isInitializing || !OnHandleException( exceptionToTest, out errorCode ) )
            {
                if ( exceptionToTest is InfoCardBaseException ) 
                {
                    // 
                    // All InfoCardExceptions are recoverable.  Get the HResult and return it. 
                    //
                    errorCode = ( (InfoCardBaseException) exceptionToTest ).NativeHResult; 
                    m_extendedErrorMessage = ( ( InfoCardBaseException ) exceptionToTest ).ExtendedMessage;
                }
                else if( m_recoverableExceptions == ExceptionList.AllNonFatal )
                { 
                    //
                    // This is a non InfoCard exception that is still recoverable. 
                    // 
                    CommunicationException ce = new CommunicationException( SR.GetString( SR.ClientAPIInfocardError ), exceptionToTest );
                    IDT.TraceAndLogException( ce ); 
                    errorCode = ((InfoCardBaseException)ce).NativeHResult;
                }
                else if ( m_recoverableExceptions.Contains( exceptionToTest.GetType() ) )
                { 
                    //
                    // This is a non InfoCard exception that is still recoverable. 
                    // 
                    errorCode = GetHResultFromException( exceptionToTest );
                } 
                else
                {
                    IDT.TraceAndLogException( e );
                    InfoCardService.Crash( e ); 
                }
            } 
            return errorCode; 
        }
 

        //
        // Summary:
        //  Preprocess the request. 
        //  Marshal all input args.
        // 
        protected virtual void PreProcessRequest() 
        {
            ProcessingException = null; 

            OnMarshalInArgs();

            if ( null != ProcessingException ) 
            {
                Exception e = ProcessingException; 
                ProcessingException = null; 
                throw IDT.ThrowHelperError( new InfoCardRequestException( e.Message, e ) );
            } 

            //
            // Check if all the data has been read
            // 
            if( InArgs.Position != InArgs.Length )
            { 
                throw IDT.ThrowHelperError( new CommunicationException( SR.GetString( SR.ServiceInvalidDataInRequest ) ) ); 
            }
 
            InArgs.Close();
        }

 
        //
        // Summary: 
        //  Postprocess the request. 
        //  Marshal all output args.
        protected virtual void PostProcessRequest() 
        {
            ProcessingException = null;
            OutArgs.Flush();
 
            OnMarshalOutArgs();
 
            if ( null != ProcessingException ) 
            {
                Exception e = ProcessingException; 
                ProcessingException = null;
                throw IDT.ThrowHelperError( new InfoCardRequestException( e.Message, e ) );
            }
 
        }
 
 
        //
        // Summary: 
        //  Process the request.
        //
        protected virtual void ProcessRequest()
        { 
            ProcessingException = null;
 
            OnProcess(); 

            if ( null != ProcessingException ) 
            {
                Exception e = ProcessingException;
                ProcessingException = null;
                throw IDT.ThrowHelperError( new InfoCardRequestException( e.Message, e ) ); 
            }
        } 
 
        //
        // Summary 
        // Enforces the control flow of processing for all requests:
        // OnMarshalInArgs, OnProcess, & OnMarshalOutArgs
        //
        public int DoProcessRequest( out string extendedMessage ) 
        {
            int errorCode = m_initHResult; 
 
            //
            // If initialization wasn't successful then simply return the initialization error code. 
            //
            if ( 0 == errorCode )
            {
                try 
                {
                    PreProcessRequest(); 
 
                    ProcessRequest();
 
                    PostProcessRequest();
                }

                #pragma warning suppress 56500  // do not catch all exceptions. System handles this in HandleException method. 
                catch ( Exception e )
                { 
                    errorCode = HandleException( e ); 
                }
            } 
            extendedMessage = m_extendedErrorMessage;
            return errorCode;
        }
 
        //
        // Summary 
        // Called from RquestFactory to associate UIAgentRequests with a 
        // client request [a.k.a the Parent request for the Ui Agent Request]
        // 
        public static Request FindRequestByHandle( int requestHandle )
        {
            lock ( s_syncRoot )
            { 
                return s_existingClientRequests[ requestHandle ];
            } 
        } 

        // 
        // Summary
        // Invoke virutal onDispose so that the derived requests
        // can do their cleanup.
        // 
        // Remarks
        // Calls virtual OnDispose so that derived classes are able to do their cleanup 
        // 
        public void Dispose()
        { 
            OnDisposeAsUser();

            if( null != m_impersonationContext )
            { 
                m_impersonationContext.Undo();
                m_impersonationContext = null; 
            } 

            OnDisposeAsSystem(); 

            //
            // The request can only be removed from the dictionary after disposal as System as the UI agent is released
            // in the client UI request OnDisposeAsSystem method and the agent may send a SendAgentStatusRequest during 
            // release.
            // 
            RemoveThisRequestFromDictionary(); 

            GC.SuppressFinalize( this ); 
        }

        protected virtual void OnInitializeAsSystem()
        { 
        }
        protected virtual void OnInitializeAsUser() 
        { 
        }
 
        protected virtual void OnDisposeAsUser()
        {

        } 

        // 
        // Summary 
        // Derived classes implement this function to read input information
        // from the input stream (InArgs) 
        //
        protected abstract void OnMarshalInArgs();

        // 
        // Summary
        // Derived classes implement this function to process their request 
        // 
        protected abstract void OnProcess();
 
        //
        // Summary
        // Derived classes implement this function to write output information
        // from managed constructs into the outpur stream (OutArgs) 
        //
        protected abstract void OnMarshalOutArgs(); 
 
        //
        // Summary 
        // Derived classes call Base.OnDisposeAsSystem() after doing their own
        // cleanup. For now, we have nothing to dispose
        //
        protected virtual void OnDisposeAsSystem() 
        {
 
        } 

        // 
        // Summary
        // Returns true if exception e is handled. Sets the out parameter to
        // appropriate error value.  This method can be overridden if subclasses
        // have any special exception handling code that they need to run.  If the method 
        // returns true then the base class will use the errorCode out parameter as the
        // error code to return to the caller. 
        // 
        protected virtual bool OnHandleException( Exception e, out int errorCode )
        { 
            errorCode = 0;
            return false;
        }
 

        // 
        // Summary 
        // Add this request to s_existingClientRequests
        // 
        private void InsertThisRequestIntoDictionary()
        {

            int requestHandle = 0; 
            lock ( s_syncRoot )
            { 
                try 
                {
                    requestHandle = s_existingClientRequests.GetNewHandle(); 
                }
                catch( IndexOutOfRangeException e )
                {
                    throw IDT.ThrowHelperError( new ServiceBusyException( SR.GetString( SR.TooManyClientRequests ), e ) ); 
                }
                m_requestHandle = requestHandle; 
                s_existingClientRequests[ m_requestHandle ] = this; 
            }
        } 

        //
        // Summary
        // Remove this request from s_existingClientRequests 
        //
        private void RemoveThisRequestFromDictionary() 
        { 
            //
            // A reference to this object exists in the static list 
            // therefore we need to do the following to allow the GC to
            // clear up
            //
            lock ( s_syncRoot ) 
            {
                s_existingClientRequests.Remove( m_requestHandle ); 
            } 
        }
   } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK