InvokerUtil.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 / ServiceModel / System / ServiceModel / Dispatcher / InvokerUtil.cs / 1 / InvokerUtil.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Dispatcher 
{
    using System; 
    using System.ServiceModel.Description; 
    using System.Reflection;
    using System.Reflection.Emit; 
    using System.Security.Permissions;
    using System.Globalization;
    using System.Security;
    using System.Diagnostics; 

    internal delegate object InvokeDelegate(object target, object[] inputs, object[] outputs); 
    internal delegate IAsyncResult InvokeBeginDelegate(object target, object[] inputs, AsyncCallback asyncCallback, object state); 
    internal delegate object InvokeEndDelegate(object target, object[] outputs, IAsyncResult result);
    internal delegate object CreateInstanceDelegate(); 

    sealed class InvokerUtil
    {
        ///  
        /// Critical - holds instance of CriticalHelper which keeps state that was produced within an assert
        ///  
        [SecurityCritical] 
        CriticalHelper helper;
 
        /// 
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        public InvokerUtil() 
        { 
            helper = new CriticalHelper();
        } 

        /// 
        /// Critical - accesses SecurityCritical helper class 'CriticalHelper'
        /// Safe - resultant delegate is self-contained and safe for general consumption, nothing else leaks 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal CreateInstanceDelegate GenerateCreateInstanceDelegate(Type type, ConstructorInfo constructor) 
        {
            return helper.GenerateCreateInstanceDelegate(type, constructor); 
        }

        /// 
        /// Critical - accesses SecurityCritical helper class 'CriticalHelper' 
        /// Safe - resultant delegate is self-contained and safe for general consumption, parameter counts are safe, nothing else leaks
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount)
        { 
            return helper.GenerateInvokeDelegate(method, out inputParameterCount, out outputParameterCount);
        }

        ///  
        /// Critical - accesses SecurityCritical helper class 'CriticalHelper'
        /// Safe - resultant delegate is self-contained and safe for general consumption, parameter count is safe, nothing else leaks 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal InvokeBeginDelegate GenerateInvokeBeginDelegate(MethodInfo method, out int inputParameterCount) 
        {
            return helper.GenerateInvokeBeginDelegate(method, out inputParameterCount);
        }
 
        /// 
        /// Critical - accesses SecurityCritical helper class 'CriticalHelper' 
        /// Safe - resultant delegate is self-contained and safe for general consumption, parameter count is safe, nothing else leaks 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal InvokeEndDelegate GenerateInvokeEndDelegate(MethodInfo method, out int outputParameterCount)
        {
            return helper.GenerateInvokeEndDelegate(method, out outputParameterCount);
        } 

        ///  
        /// Critical - handles all aspects of IL generation including initializing the DynamicMethod, which requires an elevation 
        ///            since the ILGenerator is created under an elevation, we lock down access to every aspect of the generation
        ///  
        [SecurityCritical(SecurityCriticalScope.Everything)]
        class CriticalHelper
        {
            static Type TypeOfObject = typeof(object); 

            CodeGenerator ilg; 
 
            internal CreateInstanceDelegate GenerateCreateInstanceDelegate(Type type, ConstructorInfo constructor)
            { 
                bool requiresMemberAccess = !IsTypeVisible(type) || ConstructorRequiresMemberAccess(constructor);

                this.ilg = new CodeGenerator();
                try 
                {
                    ilg.BeginMethod("Create" + type.FullName, typeof(CreateInstanceDelegate), requiresMemberAccess); 
                } 
                catch (SecurityException securityException)
                { 
                    if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
                    {
                        if (DiagnosticUtility.ShouldTraceWarning)
                        { 
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(securityException, TraceEventType.Warning);
                        } 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new SecurityException(SR.GetString(
                                    SR.PartialTrustServiceCtorNotVisible, 
                                    type.FullName)));
                    }
                    else
                    { 
                        throw;
                    } 
                } 

                if (type.IsValueType) 
                {
                    LocalBuilder instanceLocal = ilg.DeclareLocal(type, type.Name + "Instance");
                    ilg.LoadZeroValueIntoLocal(type, instanceLocal);
                    ilg.Load(instanceLocal); 
                }
                else 
                { 
                    ilg.New(constructor);
                } 
                ilg.ConvertValue(type, ilg.CurrentMethod.ReturnType);
                return (CreateInstanceDelegate)ilg.EndMethod();
            }
 
            internal InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount)
            { 
                bool requiresMemberAccess = MethodRequiresMemberAccess(method); 

                this.ilg = new CodeGenerator(); 
                try
                {
                    this.ilg.BeginMethod("SyncInvoke" + method.Name, typeof(InvokeDelegate), requiresMemberAccess);
                } 
                catch (SecurityException securityException)
                { 
                    if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission))) 
                    {
                        if (DiagnosticUtility.ShouldTraceWarning) 
                        {
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(securityException, TraceEventType.Warning);
                        }
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new SecurityException(SR.GetString(
                                    SR.PartialTrustServiceMethodNotVisible, 
                                    method.DeclaringType.FullName, 
                                    method.Name)));
                    } 
                    else
                    {
                        throw;
                    } 
                }
 
                ArgBuilder targetArg = ilg.GetArg(0); 
                ArgBuilder inputParametersArg = ilg.GetArg(1);
                ArgBuilder outputParametersArg = ilg.GetArg(2); 

                ParameterInfo[] parameters = method.GetParameters();
                LocalBuilder returnLocal = ilg.DeclareLocal(ilg.CurrentMethod.ReturnType, "returnParam");
                LocalBuilder[] parameterLocals = new LocalBuilder[parameters.Length]; 
                DeclareParameterLocals(parameters, parameterLocals);
 
                LoadInputParametersIntoLocals(parameters, parameterLocals, inputParametersArg, out inputParameterCount); 
                LoadTarget(targetArg, method.ReflectedType);
                LoadParameters(parameters, parameterLocals); 
                InvokeMethod(method, returnLocal);
                LoadOutputParametersIntoArray(parameters, parameterLocals, outputParametersArg, out outputParameterCount);

                ilg.Load(returnLocal); 
                return (InvokeDelegate)this.ilg.EndMethod();
            } 
 
            internal InvokeBeginDelegate GenerateInvokeBeginDelegate(MethodInfo method, out int inputParameterCount)
            { 
                bool requiresMemberAccess = MethodRequiresMemberAccess(method);

                this.ilg = new CodeGenerator();
                try 
                {
                    this.ilg.BeginMethod("AsyncInvokeBegin" + method.Name, typeof(InvokeBeginDelegate), requiresMemberAccess); 
                } 
                catch (SecurityException securityException)
                { 
                    if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
                    {
                        if (DiagnosticUtility.ShouldTraceWarning)
                        { 
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(securityException, TraceEventType.Warning);
                        } 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new SecurityException(SR.GetString(
                                    SR.PartialTrustServiceMethodNotVisible, 
                                    method.DeclaringType.FullName,
                                    method.Name)));
                    }
                    else 
                    {
                        throw; 
                    } 
                }
 
                ArgBuilder targetArg = ilg.GetArg(0);
                ArgBuilder inputParametersArg = ilg.GetArg(1);
                ArgBuilder callbackArg = ilg.GetArg(2);
                ArgBuilder stateArg = ilg.GetArg(3); 

                ParameterInfo[] parameters = method.GetParameters(); 
                LocalBuilder returnLocal = ilg.DeclareLocal(ilg.CurrentMethod.ReturnType, "returnParam"); 
                LocalBuilder[] parameterLocals = new LocalBuilder[parameters.Length - 2];
                DeclareParameterLocals(parameters, parameterLocals); 

                LoadInputParametersIntoLocals(parameters, parameterLocals, inputParametersArg, out inputParameterCount);
                LoadTarget(targetArg, method.ReflectedType);
                LoadParameters(parameters, parameterLocals); 
                ilg.Load(callbackArg);
                ilg.Load(stateArg); 
                InvokeMethod(method, returnLocal); 

                ilg.Load(returnLocal); 
                return (InvokeBeginDelegate)this.ilg.EndMethod();
            }

            internal InvokeEndDelegate GenerateInvokeEndDelegate(MethodInfo method, out int outputParameterCount) 
            {
                bool requiresMemberAccess = MethodRequiresMemberAccess(method); 
 
                this.ilg = new CodeGenerator();
                try 
                {
                    this.ilg.BeginMethod("AsyncInvokeEnd" + method.Name, typeof(InvokeEndDelegate), requiresMemberAccess);
                }
                catch (SecurityException securityException) 
                {
                    if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission))) 
                    { 
                        if (DiagnosticUtility.ShouldTraceWarning)
                        { 
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(securityException, TraceEventType.Warning);
                        }
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new SecurityException(SR.GetString( 
                                    SR.PartialTrustServiceMethodNotVisible,
                                    method.DeclaringType.FullName, 
                                    method.Name))); 
                    }
                    else 
                    {
                        throw;
                    }
                } 

                ArgBuilder targetArg = ilg.GetArg(0); 
                ArgBuilder outputParametersArg = ilg.GetArg(1); 
                ArgBuilder resultArg = ilg.GetArg(2);
 
                ParameterInfo[] parameters = method.GetParameters();
                LocalBuilder returnLocal = ilg.DeclareLocal(ilg.CurrentMethod.ReturnType, "returnParam");
                LocalBuilder[] parameterLocals = new LocalBuilder[parameters.Length - 1];
                DeclareParameterLocals(parameters, parameterLocals); 

                LoadZeroValueInputParametersIntoLocals(parameters, parameterLocals); 
                LoadTarget(targetArg, method.ReflectedType); 
                LoadParameters(parameters, parameterLocals);
                ilg.Load(resultArg); 
                InvokeMethod(method, returnLocal);
                LoadOutputParametersIntoArray(parameters, parameterLocals, outputParametersArg, out outputParameterCount);

                ilg.Load(returnLocal); 
                return (InvokeEndDelegate)this.ilg.EndMethod();
            } 
 
            void DeclareParameterLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals)
            { 
                for (int i = 0; i < parameterLocals.Length; i++)
                {
                    parameterLocals[i] = ilg.DeclareLocal(TypeLoader.GetParameterType(parameters[i]), "param" + i.ToString(CultureInfo.InvariantCulture));
                } 
            }
 
            void LoadInputParametersIntoLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals, ArgBuilder inputParametersArg, out int inputParameterCount) 
            {
                inputParameterCount = 0; 
                for (int i = 0; i < parameterLocals.Length; i++)
                {
                    if (ServiceReflector.FlowsIn(parameters[i]))
                    { 
                        Type parameterType = parameterLocals[i].LocalType;
                        ilg.LoadArrayElement(inputParametersArg, inputParameterCount); 
                        if (!parameterType.IsValueType) 
                        {
                            ilg.ConvertValue(TypeOfObject, parameterType); 
                            ilg.Store(parameterLocals[i]);
                        }
                        else
                        { 
                            ilg.Dup();
                            ilg.If(); 
                            ilg.ConvertValue(TypeOfObject, parameterType); 
                            ilg.Store(parameterLocals[i]);
                            ilg.Else(); 
                            ilg.Pop();
                            ilg.LoadZeroValueIntoLocal(parameterType, parameterLocals[i]);
                            ilg.EndIf();
                        } 
                        inputParameterCount++;
                    } 
                } 
            }
 
            void LoadZeroValueInputParametersIntoLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals)
            {
                for (int i = 0; i < parameterLocals.Length; i++)
                { 
                    if (ServiceReflector.FlowsIn(parameters[i]))
                    { 
                        ilg.LoadZeroValueIntoLocal(parameterLocals[i].LocalType, parameterLocals[i]); 
                    }
                } 
            }

            void LoadTarget(ArgBuilder targetArg, Type targetType)
            { 
                ilg.Load(targetArg);
                ilg.ConvertValue(targetArg.ArgType, targetType); 
                if (targetType.IsValueType) 
                {
                    LocalBuilder targetLocal = ilg.DeclareLocal(targetType, "target"); 
                    ilg.Store(targetLocal);
                    ilg.LoadAddress(targetLocal);
                }
            } 

            void LoadParameters(ParameterInfo[] parameters, LocalBuilder[] parameterLocals) 
            { 
                for (int i = 0; i < parameterLocals.Length; i++)
                { 
                    if (parameters[i].ParameterType.IsByRef)
                        ilg.Ldloca(parameterLocals[i]);
                    else
                        ilg.Ldloc(parameterLocals[i]); 
                }
            } 
 
            void InvokeMethod(MethodInfo method, LocalBuilder returnLocal)
            { 
                ilg.Call(method);
                if (method.ReturnType == typeof(void))
                    ilg.Load(null);
                else 
                    ilg.ConvertValue(method.ReturnType, ilg.CurrentMethod.ReturnType);
                ilg.Store(returnLocal); 
            } 

            void LoadOutputParametersIntoArray(ParameterInfo[] parameters, LocalBuilder[] parameterLocals, ArgBuilder outputParametersArg, out int outputParameterCount) 
            {
                outputParameterCount = 0;
                for (int i = 0; i < parameterLocals.Length; i++)
                { 
                    if (ServiceReflector.FlowsOut(parameters[i]))
                    { 
                        ilg.Load(outputParametersArg); 
                        ilg.Load(outputParameterCount);
                        ilg.Load(parameterLocals[i]); 
                        ilg.ConvertValue(parameterLocals[i].LocalType, TypeOfObject);
                        ilg.Stelem(TypeOfObject);
                        outputParameterCount++;
                    } 
                }
            } 
 
            static bool IsTypeVisible(Type t)
            { 
                if (t.Module == typeof(InvokerUtil).Module)
                    return true;

                if (!t.IsVisible) 
                    return false;
 
                foreach (Type genericType in t.GetGenericArguments()) 
                {
                    if (!genericType.IsGenericParameter && !IsTypeVisible(genericType)) 
                        return false;
                }

                return true; 
            }
 
            static bool ConstructorRequiresMemberAccess(ConstructorInfo ctor) 
            {
                return ctor != null && (!ctor.IsPublic || !IsTypeVisible(ctor.DeclaringType)) && ctor.Module != typeof(InvokerUtil).Module; 
            }

            static bool MethodRequiresMemberAccess(MethodInfo method)
            { 
                return method != null && (!method.IsPublic || !IsTypeVisible(method.DeclaringType)) && method.Module != typeof(InvokerUtil).Module;
            } 
        } 
    }
} 

// 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