RemotingServices.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Runtime / Remoting / RemotingServices.cs / 1305376 / RemotingServices.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
//
// File: RemotingServices.cs 
// 
// [....]
// 
// Author(s):   Gopal Kakivaya (GopalK)
//
// Purpose: Defines various remoting related services such as
//          marshal, unmarshal, connect, wrap, unwrap etc. 
//
// 
namespace System.Runtime.Remoting { 
    using System;
    using System.Text; 
    using System.Collections;
    using System.Runtime.Serialization;
    using System.IO;
    using System.Reflection; 
    using System.Reflection.Cache;
    using System.Runtime.CompilerServices; 
    using CultureInfo = System.Globalization.CultureInfo; 
    using System.Runtime.InteropServices;
    using System.Threading; 
    using System.Runtime.Remoting.Activation;
    using System.Runtime.Remoting.Contexts;
    using System.Runtime.Remoting.Lifetime;
    using System.Runtime.Remoting.Messaging; 
    using System.Runtime.Remoting.Metadata;
    using System.Runtime.Remoting.Proxies; 
    using System.Runtime.Remoting.Channels; 
    using System.Runtime.Remoting.Services;
    using RemotingConfigInfo = System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo; 
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Security.Permissions;
    using System.Runtime.ConstrainedExecution;
    using System.Runtime.Versioning; 
    using System.Diagnostics.Contracts;
 
 
    // Implements various remoting services
[System.Runtime.InteropServices.ComVisible(true)] 
    public static class RemotingServices
    {

        private const BindingFlags LookupAll = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; 
        private const String FieldGetterName = "FieldGetter";
        private const String FieldSetterName = "FieldSetter"; 
        private const String IsInstanceOfTypeName = "IsInstanceOfType"; 
        private const String CanCastToXmlTypeName = "CanCastToXmlType";
        private const String InvokeMemberName = "InvokeMember"; 

        internal static SecurityPermission s_RemotingInfrastructurePermission;
        internal static Assembly s_MscorlibAssembly;
        private static MethodBase s_FieldGetterMB; 
        private static MethodBase s_FieldSetterMB;
        private static MethodBase s_IsInstanceOfTypeMB; 
        private static MethodBase s_CanCastToXmlTypeMB; 
        private static MethodBase s_InvokeMemberMB;
 
        private static bool s_bRemoteActivationConfigured;

        // have we registered the well known channels
        private static bool s_bRegisteredWellKnownChannels; 
        // are we in the middle of registering well known channels
        private static bool s_bInProcessOfRegisteringWellKnownChannels; 
        private static Object s_delayLoadChannelLock; 

        // Note: This class can be loaded into a new appdomain before the appdomain is fully setup 
        // security-wise.  Therefore, I've wrapped all the static initialization into an explicit
        // static class initializer and placed an assert that will terminate any stackwalk before
        // it reaches the appdomain transition.
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        static RemotingServices() 
        { 
            System.Security.CodeAccessPermission.Assert(true);
            s_RemotingInfrastructurePermission= new SecurityPermission(SecurityPermissionFlag.Infrastructure); 
            s_MscorlibAssembly = typeof(RemotingServices).Assembly;
            s_FieldGetterMB = null;
            s_FieldSetterMB = null;
            s_bRemoteActivationConfigured = false; 
            s_bRegisteredWellKnownChannels = false;
            s_bInProcessOfRegisteringWellKnownChannels = false; 
            s_delayLoadChannelLock = new Object(); 
        }
 
        //
        //Native Static Methods
        //
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [Pure]
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall), 
        ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public static extern bool IsTransparentProxy(Object proxy); 


       //   Check whether the given object's context is the same as
       //   the current context. 
       //
       // 
       // 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public static bool IsObjectOutOfContext(Object tp) 
        {
            if (!IsTransparentProxy(tp))
            {
                return false; 
            }
 
            RealProxy rp = GetRealProxy(tp); 
            Identity id = rp.IdentityObject;
            ServerIdentity serverID = id as ServerIdentity; 
            if ((null == serverID) || !(rp is RemotingProxy))
            {
                return true;
            } 

            return(Thread.CurrentContext != serverID.ServerContext); 
        } 

 
       //   Check whether the given object's app domain is the same as
       //   the current app domain
       //
       // 
       //
        public static bool IsObjectOutOfAppDomain(Object tp) 
        { 
            return IsClientProxy(tp);
        } // IsObjectOutOfAppDomain 


        internal static bool IsClientProxy(Object obj)
        { 
            MarshalByRefObject mbr = obj as MarshalByRefObject;
            if (mbr == null) 
                return false; 

            bool bIsClientProxy = false; 

            bool fServer;
            Identity id = MarshalByRefObject.GetIdentity(mbr, out fServer);
            // If the identity is null, this is defintely a locally hosted object; 
            // otherwise...(see if statement below).
            if (id != null) 
            { 
                if (!(id is ServerIdentity))
                    bIsClientProxy = true; 
            }

            return bIsClientProxy;
        } // IsClientProxy 

 
       //   Check whether the given object's process is the same as 
       //   the current process
       // 
       //
       //
        [System.Security.SecurityCritical]  // auto-generated
        internal static bool IsObjectOutOfProcess(Object tp) 
        {
            if (!IsTransparentProxy(tp)) 
                return false; 

            RealProxy rp = GetRealProxy(tp); 
            Identity id = rp.IdentityObject;
            if (id is ServerIdentity)
                return false;
            else 
            {
                if (null != id) 
                { 
                    ObjRef objRef = id.ObjectRef;
                    if (objRef != null && objRef.IsFromThisProcess()) 
                    {
                        return false;
                    }
                    else 
                    {
                        return true; 
                    } 
                }
                // assume out of process 
                return true;
            }

        } // IsObjectOutOfProcess 

       //   Get the real proxy backing the transparent proxy 
       // 
       //
       // 
        [System.Security.SecurityCritical]  // auto-generated_required
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        public static extern RealProxy GetRealProxy(Object proxy);
 
 
       //   Create a transparent proxy given an instance of a real proxy and type
       // 
       //
       //
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Object CreateTransparentProxy( 
                                            RealProxy rp, 
                                            RuntimeType typeToProxy,
                                            IntPtr stub, 
                                            Object stubData);

        // Note: for each of these calls that take a RuntimeXXX reflection
        // structure, there is a wrapper that takes XXX and throws if it is 
        // not a RuntimeXXX. This is to avoid clutter in code where these
        // methods are called. (48721)  Ideally this should have been done 
        // as a breaking change to the public APIs that use them! 

        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object CreateTransparentProxy(
            RealProxy rp,
            Type typeToProxy,
            IntPtr stub, 
            Object stubData)
        { 
            RuntimeType rTypeToProxy = typeToProxy as RuntimeType; 
            if (rTypeToProxy == null)
                throw new ArgumentException( 
                            String.Format(
                                CultureInfo.CurrentCulture, Environment.GetResourceString(
                                    "Argument_WrongType"),
                                "typeToProxy" 
                                )
                            ); 
 
            return CreateTransparentProxy(
                        rp, 
                        rTypeToProxy,
                        stub,
                        stubData);
        } 

 
 
       //   Allocate an uninitialized object of the given type.
       // 
       //
       //
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern MarshalByRefObject AllocateUninitializedObject( 
                                                    RuntimeType objectType); 

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern void CallDefaultCtor(Object o);
 

        [System.Security.SecurityCritical]  // auto-generated 
        internal static MarshalByRefObject AllocateUninitializedObject( 
            Type objectType)
        { 
            RuntimeType rObjectType = objectType as RuntimeType;
            if (rObjectType == null)
                throw new ArgumentException(
                            String.Format( 
                                CultureInfo.CurrentCulture, Environment.GetResourceString(
                                    "Argument_WrongType"), 
                                "objectType" 
                                )
                            ); 
            return AllocateUninitializedObject(
                        rObjectType);
        }
 
       //   Allocate an Initialized object of the given type.
       //       runs the default constructor 
       // 
       //
        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern MarshalByRefObject AllocateInitializedObject(
                                                        RuntimeType objectType); 

 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static MarshalByRefObject AllocateInitializedObject(
            Type objectType) 
        {
            RuntimeType rObjectType = objectType as RuntimeType;
            if (rObjectType == null)
                throw new ArgumentException( 
                            String.Format(
                                CultureInfo.CurrentCulture, Environment.GetResourceString( 
                                    "Argument_WrongType"), 
                                "objectType"
                                ) 
                            );
            return AllocateInitializedObject(
                        rObjectType);
        } 

 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static bool RegisterWellKnownChannels()
        { 
            // Any code coming through this method MUST not exit
            //   until the well known channels have been registered
            //   (unless we are reentering in the call to
            //    RefreshChannelData() while registering a well known 
            //    channel).
            if (!s_bRegisteredWellKnownChannels) 
            { 
                bool fLocked = false;
                Object configLock = Thread.GetDomain().RemotingData.ConfigLock; 
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    Monitor.Enter(configLock, ref fLocked); 
                    if (!s_bRegisteredWellKnownChannels &&
                        !s_bInProcessOfRegisteringWellKnownChannels) 
                    { 

                        // we set this flag true before registering channels to prevent reentrancy 
                        //   when we go to refresh the channel data at the end of the call to
                        //   ChannelServices.RegisterChannel().
                        s_bInProcessOfRegisteringWellKnownChannels = true;
                        CrossAppDomainChannel.RegisterChannel(); 
                        s_bRegisteredWellKnownChannels = true;
                    } 
                } 
                finally
                { 
                    if (fLocked)
                    {
                        Monitor.Exit(configLock);
                    } 
                }
            } 
            return true; 
        } // RegisterWellKnownChannels
 

        [System.Security.SecurityCritical]  // auto-generated
        internal static void InternalSetRemoteActivationConfigured()
        { 
            if (!s_bRemoteActivationConfigured)
            { 
                nSetRemoteActivationConfigured(); 
                s_bRemoteActivationConfigured = true;
            } 
        } // InternalSetRemoteActivationConfigured


        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern void nSetRemoteActivationConfigured(); 

 
        [System.Security.SecurityCritical]  // auto-generated_required
        public static String GetSessionIdForMethodMessage(IMethodMessage msg)
        {
            return msg.Uri; 
        } // GetSessionIdForMessage
 
        [System.Security.SecuritySafeCritical]  // auto-generated 
        public static Object GetLifetimeService(MarshalByRefObject obj)
        { 
            if(null != obj)
            {
                return obj.GetLifetimeService();
            } 
            else
            { 
                return null; 
            }
        } 

        [System.Security.SecurityCritical]  // auto-generated_required
        public static String GetObjectUri(MarshalByRefObject obj)
        { 
            // Retrieve the uri for the object. If it doesn't have an identity
            //   we'll just return null (this encompasses the case of an actual 
            //   object not having been marshalled yet. 

            bool fServer; 
            Identity id = MarshalByRefObject.GetIdentity(obj, out fServer);

            if(null != id)
                return id.URI; 
            else
                return null; 
        } // GetObjectUri 

 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)]
        public static void SetObjectUriForMarshal( MarshalByRefObject obj, String uri)
        { 
            // if obj is ever Marshal'd it should use this uri. If a uri has
            //   already been assigned to the object, it should throw. 
 
            Message.DebugOut("Entered SetObjectUriForMarshal \n");
 
            Identity idObj = null;
            Identity srvIdObj = null;

            bool fServer; 
            idObj = MarshalByRefObject.GetIdentity(obj, out fServer);
            srvIdObj = idObj as ServerIdentity; 
 
            // Ensure that if we have a transparent proxy then we are not given a remoting
            // proxy. This routine should only be called for objects that 
            // live in this AppDomains.
            if ((idObj != null) &&
                (srvIdObj == null)) // <-- means idObj is not a ServerIdentity
            { 
                throw new RemotingException(
                    Environment.GetResourceString( 
                        "Remoting_SetObjectUriForMarshal__ObjectNeedsToBeLocal")); 
            }
 

            if ((idObj != null) && (idObj.URI != null))
            {
                throw new RemotingException( 
                    Environment.GetResourceString(
                        "Remoting_SetObjectUriForMarshal__UriExists")); 
            } 

 
            if (idObj == null)
            {
                // obj is not ContextBound
                Contract.Assert(!(obj is ContextBoundObject), "ContextBoundObject's shouldn't get here."); 

                // Create a new server identity and add it to the 
                // table. IdentityHolder will take care of ----s 
                Context serverCtx = null;
 
                serverCtx = Thread.GetDomain().GetDefaultContext();

                Contract.Assert(null != serverCtx, "null != serverCtx");
 
                ServerIdentity serverID = new ServerIdentity(obj, serverCtx, uri);
 
                // set the identity 
                idObj = obj.__RaceSetServerIdentity(serverID);
                Contract.Assert(idObj == MarshalByRefObject.GetIdentity(obj), "Bad ID state!" ); 

                // If our serverID isn't used then someone else marshalled the object
                // before we could set the uri.
                if (idObj != serverID) 
                {
                    throw new RemotingException( 
                        Environment.GetResourceString( 
                            "Remoting_SetObjectUriForMarshal__UriExists"));
                } 
            }
            else
            {
                // This is the ContextBoundObject case 
                Contract.Assert(obj is ContextBoundObject, "Object should have been a ContextBoundObject.");
 
                idObj.SetOrCreateURI(uri, true); 
            }
 
            Message.DebugOut("Created ServerIdentity \n");
        } // SetObjectUriForMarshal

 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] 
        public static ObjRef Marshal(MarshalByRefObject Obj) 
        {
            return MarshalInternal(Obj, null, null); 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] 
        public static ObjRef Marshal(MarshalByRefObject Obj, String URI)
        { 
            return MarshalInternal(Obj, URI, null); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)]
        public static ObjRef Marshal(MarshalByRefObject Obj, String ObjURI, Type RequestedType)
        { 
            return MarshalInternal(Obj, ObjURI, RequestedType);
        } 
 
        // Internal flavor without security!
        [System.Security.SecurityCritical]  // auto-generated 
        internal static ObjRef MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType)
        {
            return MarshalInternal(Obj, ObjURI, RequestedType, true);
        } 
        // Internal flavor without security!
        [System.Security.SecurityCritical]  // auto-generated 
        internal static ObjRef MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType, bool updateChannelData) 
        {
            BCLDebug.Trace("REMOTE", "Entered Marshal for URI" +  ObjURI + "\n"); 

            if (null == Obj)
                return null;
 
            ObjRef objectRef = null;
            Identity idObj = null; 
 
            idObj = GetOrCreateIdentity(Obj, ObjURI);
            if (RequestedType != null) 
            {
                ServerIdentity srvIdObj = idObj as ServerIdentity;
                if (srvIdObj != null)
                { 
                    // If more than one thread, marshals with different types the
                    // results would be non-deterministic, so we just let the last 
                    // call win (also allows type to be marshalled a second time 
                    // to change the exposed type).
                    srvIdObj.ServerType = RequestedType; 
                    srvIdObj.MarshaledAsSpecificType = true;
                }
            }
 
            // If there is no objref associated with the identity then go ahead
            // and create one and stick it back into the identity object 
 
#if _DEBUG
            idObj.AssertValid(); 
#endif

            Contract.Assert(null != idObj.ObjURI,"null != idObj.ObjURI");
 
            Message.DebugOut("RemotingServices::Marshal: trying to create objref\n");
 
            // We should definitely have an identity object at this point of time 
            Contract.Assert(null != idObj,"null != idObj");
 
            // Extract the objref from the identity
            objectRef = idObj.ObjectRef;
            if (null == objectRef)
            { 
                Message.DebugOut("RemotingServices::Marshal: really trying to create objref\n");
 
                if (IsTransparentProxy(Obj)) 
                {
                    RealProxy realProxy = GetRealProxy(Obj); 
                    Contract.Assert(null != realProxy,"null != realProxy");
                    objectRef = realProxy.CreateObjRef(RequestedType);
                }
                else 
                {
                    // Create a new object ref which contains the default information 
                    objectRef = Obj.CreateObjRef(RequestedType); 
                }
 
                Message.DebugOut("RemotingServices::Marshal: created objref\n");
                if (idObj == null || objectRef == null)
                    throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMarshalByRefObject"), "Obj");
 
                // The ObjectRef property setter will take care of ----s
                objectRef = idObj.RaceSetObjRef(objectRef); 
            } 

 
            // Retime lease on every marshal on the server side
            // and extend lease on every marshal on the client side - GopalK
            ServerIdentity srvId = idObj as ServerIdentity;
            if (srvId != null) 
            {
                // Ensure that the lease is started soon as the object is 
                // marshaled. 
                MarshalByRefObject obj = null;
                // This call forces creation of the lifetime lease sink. 
                srvId.GetServerObjectChain(out obj);

                // Server side ... object being marshaled => give it another
                // full lease 
                Lease lease = idObj.Lease;
                if (lease != null) 
                { 
                    // We always make Identity reference our own Lease though
                    // the actual object implements its own ILease object. 
                    // This seems completely broken. Further, ILease interface
                    // should have the activate method.  - GopalK

                    // This lock ensures coordination with the lifetime service 
                    // which might have decided to Disconnect the object about
                    // the same time as it is being marshaled 
                    lock (lease) 
                    {
                        if (lease.CurrentState == LeaseState.Expired) 
                        {
                            // Lease.Renew is a no-op if LeaseState==Expired
                            // So we do a full ActivateLease
                            lease.ActivateLease(); 
                        }
                        else 
                        { 
                            // Lease is still around. Just increase the time
                            lease.RenewInternal(idObj.Lease.InitialLeaseTime); 
                        }
                    }
                }
 
                // Every marshal should also ensure that the channel data
                // being carried in the objRef reflects the latest data from 
                // regisetered channels 
                // <
                if (updateChannelData && objectRef.ChannelInfo != null) 
                {
                    // Create the channel info
                    Object[] channelData = ChannelServices.CurrentChannelData;
                    // Make sure the channelInfo only has x-appdomain data since the objref is agile while other 
                    // channelData might not be and regardless this data is useless for an appdomain proxy
                    if (!(Obj is AppDomain)) 
                        objectRef.ChannelInfo.ChannelData = channelData; 
                    else
                    { 
                        int channelDataLength = channelData.Length;
                        Object[] newChannelData = new Object[channelDataLength];
                        // Clone the data so that we dont [....] the current appdomain data which is stored
                        // as a static 
                        Array.Copy(channelData, newChannelData, channelDataLength);
                        for (int i = 0; i < channelDataLength; i++) 
                        { 
                            if (!(newChannelData[i] is CrossAppDomainData))
                                newChannelData[i] = null; 
                        }
                        objectRef.ChannelInfo.ChannelData = newChannelData;
                    }
                } 
            }
            else 
            { 
#if false
                /* 



*/ 
                ILease lease = idObj.Lease;
                if (lease == null) 
                { 
                    lease = (ILease)Obj.GetLifetimeService();
                } 
                if (lease != null)
                {
                    lease.Renew(lease.RenewOnCallTime);
                } 
#endif
            } 
 
            // Notify TrackingServices that an object has been marshaled
            // NOTE: This call also keeps the object alive otherwise GC 
            // can report it as dead anytime inside this call when it thinks
            // that the object will no longer be referenced, either inside
            // this call or outside.
            /* < 
*/
 
            TrackingServices.MarshaledObject(Obj, objectRef); 
            return objectRef;
        } 

        // Gets or generates the identity if one is not present and then returns
        // it to the caller.
        [System.Security.SecurityCritical]  // auto-generated 
        private static Identity GetOrCreateIdentity(
            MarshalByRefObject Obj, 
            String ObjURI) 
        {
            Identity idObj = null; 
            if (IsTransparentProxy(Obj))
            {
                Message.DebugOut("Marshaling proxy \n");
 
                RealProxy realProxy = GetRealProxy(Obj);
                Contract.Assert(null != realProxy,"null != realProxy"); 
 
                idObj = realProxy.IdentityObject;
                if(null == idObj) 
                {
                    // passing the strongIdentity flag will ensure that a weak
                    // reference to the identity will get converted to a strong
                    // one so as to keep the object alive (and in control of 
                    // lifeTimeServices)
 
                    idObj = IdentityHolder.FindOrCreateServerIdentity( 
                                                Obj,
                                                ObjURI, 
                                                IdOps.StrongIdentity);

                    idObj.RaceSetTransparentProxy(Obj);
                } 

                // At this point of time we should have an identity 
                Contract.Assert(null != idObj, "null != idObj"); 

 
                ServerIdentity srvID = idObj as ServerIdentity;
                if (srvID != null)
                {
                    // We are marshaling a proxy with a serverIdentity 
                    // associated with it but with no URI generated yet.
                    // For a genuine proxy case we will always have a URI 
                    // AND it will be  a client ID! 
                    // So if we are here this must be a SrvID
                    // for a ContextBoundObject 
                    Contract.Assert(srvID != null && Obj is ContextBoundObject,
                        "This case should only be hit for ContextBoundObjects & ServerIdentity!");
                    Message.DebugOut("Marshal::Looking up server side identity \n");
#if _DEBUG 
                    srvID.AssertValid();
#endif 
 
                    // passing the strongIdentity flag will ensure that a weak
                    // reference to the identity will get converted to a strong 
                    // one so as to keep the object alive (and in control of
                    // lifeTimeServices)

                    idObj = IdentityHolder.FindOrCreateServerIdentity( 
                                srvID.TPOrObject,
                                ObjURI, 
                                IdOps.StrongIdentity); 

                    // if an objURI was specified we need to make sure that 
                    //   the same one was used.
                    if ((null != ObjURI) &&
                        (ObjURI != Identity.RemoveAppNameOrAppGuidIfNecessary(
                                                idObj.ObjURI))) 
                    {
                        throw new RemotingException( 
                            Environment.GetResourceString( 
                                "Remoting_URIExists"));
                    } 

                    // We create a unique ID for an object and never
                    // change it!
                    Contract.Assert(srvID == idObj, "Bad ID Table state!"); 
                }
                else 
                { 
                    // We are marshaling a proxy with a (client)Identity associated with it
                    // It must already have a URI. 
                    Message.DebugOut("Marshal::Client side identity \n");
                    Contract.Assert(idObj.ObjURI != null, "Client side id without URI!");

                    // 
                    // One cannot associate a URI with a proxy generated by us
                    // because either a URI was generated at the server side for the object 
                    // it represents or it is a well known object in which case the URI is known. 
                    //
                    // For custom proxies this restriction is relaxed because we treat the 
                    // transparent proxy as the server object for such cases.
                    //
                    if ((null != ObjURI) && (ObjURI != idObj.ObjURI))
                    { 
                        throw new RemotingException(
                            Environment.GetResourceString( 
                                "Remoting_URIToProxy")); 
                    }
                } 

                Contract.Assert(null != idObj.ObjURI,"null != idObj.ObjURI");
            }
            else 
            {
                // Find or Add the object identity to the identity table 
                Message.DebugOut("Marshaling object \n"); 

                // passing the strongIdentity flag will ensure that a weak 
                // reference to the identity will get converted to a strong
                // one so as to keep the object alive (and in control of
                // lifeTimeServices)
 
                // The object may have an ID if it was marshaled but its lease
                // timed out. 
#if _DEBUG 
                ServerIdentity idTmp =
                    (ServerIdentity) MarshalByRefObject.GetIdentity(Obj); 
#endif


 
                idObj = IdentityHolder.FindOrCreateServerIdentity(
                                            Obj, 
                                            ObjURI, 
                                            IdOps.StrongIdentity);
 
                // If the object had an ID to begin with that is the one
                // we must have set in the table.
#if _DEBUG
                Contract.Assert(idTmp==null || idTmp == idObj, "Bad ID Table state!"); 
#endif
            } 
 
            return idObj;
        } 

        [System.Security.SecurityCritical]  // auto-generated_required
        public static void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
        { 
            if (obj == null)
            { 
                throw new ArgumentNullException("obj"); 
            }
 
            if (info==null) {
                throw new ArgumentNullException("info");
            }
            Contract.EndContractBlock(); 

            ObjRef or = RemotingServices.MarshalInternal( 
                                            (MarshalByRefObject)obj, 
                                            null,
                                            null); 

            or.GetObjectData(info, context);
        } // GetObjectData
 
        [System.Security.SecurityCritical]  // auto-generated_required
        public static Object Unmarshal(ObjRef objectRef) 
        { 
            return InternalUnmarshal(objectRef, null, false);
        } 

        [System.Security.SecurityCritical]  // auto-generated_required
        public static Object Unmarshal(ObjRef objectRef, bool fRefine)
        { 
            return InternalUnmarshal(objectRef, null, fRefine);
        } 
 

        [System.Security.SecurityCritical]  // auto-generated_required 
[System.Runtime.InteropServices.ComVisible(true)]
        public static Object Connect(Type classToProxy, String url)
        {
            return Unmarshal(classToProxy, url, null); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated_required 
[System.Runtime.InteropServices.ComVisible(true)]
        public static Object Connect(Type classToProxy, String url, Object data) 
        {
            return Unmarshal(classToProxy, url, data);
        }
 

        [System.Security.SecurityCritical]  // auto-generated_required 
        public static bool Disconnect(MarshalByRefObject obj) 
        {
            return Disconnect(obj, true); 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal static bool Disconnect(MarshalByRefObject obj, bool bResetURI) 
        {
            if (obj == null) 
            { 
                throw new ArgumentNullException("obj");
            } 
            Contract.EndContractBlock();

            BCLDebug.Trace("REMOTE", "RemotingServices.Disconnect ", obj, " for context ", Thread.CurrentContext);
 
            // We can extract the identity either from the remoting proxy or
            // the server object depending on whether we are in the 
            // context/appdomain that the object was created in or outside 
            // the context/appdomain.
            bool fServer; 
            Identity idrem = MarshalByRefObject.GetIdentity(obj, out fServer);

            // remove the identity entry for this object (if it exists)
            bool fDisconnect = false; 
            if(idrem != null)
            { 
                // Disconnect is supported only on the server side currently 
                if(idrem is ServerIdentity)
                { 
                    // Disconnect is a no op if the object was never marshaled
                    if(idrem.IsInIDTable())
                    {
                        // When a user calls Disconnect we reset the URI but 
                        // when lifetime service calls Disconnect we don't
                        IdentityHolder.RemoveIdentity(idrem.URI, bResetURI); 
                        fDisconnect = true; 
                    }
                } 
                else
                {
                    // <
 
                    throw new RemotingException(
                        Environment.GetResourceString("Remoting_CantDisconnectClientProxy")); 
                } 

                // Notify TrackingServices that an object has been disconnected 
                TrackingServices.DisconnectedObject(obj);
            }

            Message.DebugOut("Disconnect:: returning " + fDisconnect + 
                             " for context " + Thread.CurrentContext +
                             "\n"); 
 
            return fDisconnect;
        } 

        [System.Security.SecurityCritical]  // auto-generated_required
        public static IMessageSink GetEnvoyChainForProxy(MarshalByRefObject obj)
        { 
            IMessageSink envoyChain = null;
 
            // Extract the envoy chain only if the object is a proxy 
            if(IsObjectOutOfContext(obj))
            { 
                RealProxy rp = GetRealProxy(obj);
                Identity id = rp.IdentityObject;
                if(null != id)
                { 
                    envoyChain = id.EnvoyChain;
                } 
            } 

            return envoyChain; 
        }

        [System.Security.SecurityCritical]  // auto-generated_required
        public static ObjRef GetObjRefForProxy(MarshalByRefObject obj) 
        {
            ObjRef objRef = null; 
            if (!IsTransparentProxy(obj)) 
            {
                throw new RemotingException( 
                    Environment.GetResourceString(
                        "Remoting_Proxy_BadType"));
            }
            RealProxy rp = GetRealProxy(obj); 
            Identity id = rp.IdentityObject;
            if (null != id) 
            { 
                objRef = id.ObjectRef;
            } 
            return objRef;
        }

        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object Unmarshal(Type classToProxy, String url)
        { 
            return Unmarshal(classToProxy, url, null); 
        }
 

        [System.Security.SecurityCritical]  // auto-generated
        internal static Object Unmarshal(Type classToProxy, String url, Object data)
        { 
            if (null == classToProxy)
            { 
                throw new ArgumentNullException("classToProxy"); 
            }
 
            if (null == url)
            {
                throw new ArgumentNullException("url");
            } 
            Contract.EndContractBlock();
 
            if (!classToProxy.IsMarshalByRef && !classToProxy.IsInterface) 
            {
                throw new RemotingException( 
                    Environment.GetResourceString(
                        "Remoting_NotRemotableByReference"));
            }
 
            BCLDebug.Trace("REMOTE", "RemotingService::Unmarshal for URL" + url + "and for Type" + classToProxy);
 
                        // See if we have already unmarshaled this (wellKnown) url 
            Identity idObj = IdentityHolder.ResolveIdentity(url);
            Object proxy = null; 
            if (idObj == null
                || idObj.ChannelSink == null || idObj.EnvoyChain == null)
            {
                String objectURI = null; 
                IMessageSink chnlSink = null;
                IMessageSink envoySink = null; 
                // Create the envoy and channel sinks 
                objectURI = CreateEnvoyAndChannelSinks(url, data, out chnlSink, out envoySink);
 
                // ensure that we were able to create a channel sink
                if (chnlSink == null)
                {
                    throw new RemotingException( 
                        String.Format(
                            CultureInfo.CurrentCulture, Environment.GetResourceString( 
                                "Remoting_Connect_CantCreateChannelSink"), 
                            url));
                } 

                // Do not allow Connect() with null objUri (eg. http://localhost/)
                if (objectURI == null)
                { 
                    throw new ArgumentException(
                        Environment.GetResourceString( 
                            "Argument_InvalidUrl")); 

                } 

#if false
                // GopalK: Return the server object if the object uri is in the IDTable and is of type
                // ServerIdentity and the object URI starts with application name 
                ServerIdentity srvId =
                    IdentityHolder.ResolveIdentity(objectURI) as ServerIdentity; 
                if (srvId != null 
                    && objectURI.StartsWith(RemotingConfigHandler.ApplicationName, StringComparison.Ordinal))
                { 
                    return srvId.ServerObject;
                }
#endif
 
                // Try to find an existing identity or create a new one
                // Note: we create an identity entry hashed with the full url. This 
                // means that the same well known object could have multiple 
                // identities on the client side if it is connected through urls
                // that have different string representations. 

                // <

 

                idObj = IdentityHolder.FindOrCreateIdentity(objectURI, url, null); 
 
                // Set the envoy and channel sinks in a thread safe manner
                SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink); 
            }

            // Get the proxy represented by the identity object
            proxy = GetOrCreateProxy(classToProxy, idObj); 

            Message.DebugOut("RemotingService::Unmarshal returning "); 
 
            return proxy;
        } 

        [System.Security.SecurityCritical]  // auto-generated
        internal static Object Wrap(ContextBoundObject obj)
        { 
            return Wrap(obj, null, true);
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static Object Wrap(ContextBoundObject obj, Object proxy, bool fCreateSinks) 
        {
            Message.DebugOut("Entering Wrap for context " + Thread.CurrentContext + "\n");

            if ((null != obj) && (!IsTransparentProxy(obj))) 
            {
                Contract.Assert(obj.GetType().IsContextful,"objType.IsContextful"); 
                Message.DebugOut("Wrapping object \n"); 
                Identity idObj = null;
 
                if (proxy != null)
                {
                    // We will come here for strictly x-context activations
                    // since a proxy has already been created and supplied 
                    // through the construction message frame (GetThisPtr()).
                    RealProxy rp = GetRealProxy(proxy); 
                    if (rp.UnwrappedServerObject == null) 
                    {
                        rp.AttachServerHelper(obj); 
                    }
                    idObj = MarshalByRefObject.GetIdentity(obj);
                }
                else 
                {
                    // Proxy is null when Wrap() is called the second 
                    // time during activation 
                    // It also will be null when a ContextBoundObject
                    // is being activated from a remote client. 
                    idObj = IdentityHolder.FindOrCreateServerIdentity(
                                obj,
                                null,
                                IdOps.None); 
                }
 
                //********************WARNING******************************* 
                // Always create the proxy before calling out to user code
                // so that any recursive calls by JIT to wrap will return this 
                // proxy.
                //**********************************************************
                // Get the proxy represented by the identity object
                proxy = GetOrCreateProxy(idObj, proxy, true); 

                // EXTENSIBILITY: 
                GetRealProxy(proxy).Wrap(); 

                if (fCreateSinks) 
                {
                    IMessageSink chnlSink = null;
                    IMessageSink envoySink = null;
                    // Create the envoy sinks and channel sink 
                    CreateEnvoyAndChannelSinks((MarshalByRefObject)proxy, null, out chnlSink, out envoySink);
 
                    // Set the envoy and channel sinks in a thread safe manner 
                    SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
                } 

                // This will handle the case where we call Wrap() with
                // a null proxy for real remote activation of ContextFul types.
                RealProxy rp2 = GetRealProxy(proxy); 
                if (rp2.UnwrappedServerObject == null)
                { 
                    rp2.AttachServerHelper(obj); 
                }
                Message.DebugOut("Leaving Wrap with proxy \n"); 
                return proxy;
            }
            else
            { 
                Message.DebugOut("Leaving Wrap with passed in object\n");
 
                // Default return value is the object itself 
                return obj;
            } 
        } // Wrap


        // This relies on the fact that no object uri is allowed to contain a slash 
        //   (in some cases, we might want to do something intelligent by parsing
        //    the uri with the right channel, but that isn't possible in all cases). 
        internal static String GetObjectUriFromFullUri(String fullUri) 
        {
            if (fullUri == null) 
                return null;

            int index = fullUri.LastIndexOf('/');
            if (index == -1) 
                return fullUri;
 
            return fullUri.Substring(index + 1); 
        } // GetObjectUriFromFullUri
 

       //
       //
        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        internal static extern Object Unwrap(ContextBoundObject obj); 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Object AlwaysUnwrap(ContextBoundObject obj);

 
       // This method does the actual work of Ma
       // 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static Object InternalUnmarshal( 
            ObjRef objectRef,
            Object proxy,
            bool fRefine)
        { 
            Object obj = null;
            Identity idObj = null; 
 
            Context currContext = Thread.CurrentContext;
            Message.DebugOut("RemotingServices::InternalUnmarshal:  Current context id: " +  (currContext.ContextID).ToString("x") + "\n"); 

            // This routine can be supplied a custom objref or an objref
            // generated by us. We do some sanity checking on the objref
            // to make sure that it is valid 
            if (!ObjRef.IsWellFormed(objectRef))
            { 
                throw new ArgumentException( 
                String.Format(
                    CultureInfo.CurrentCulture, Environment.GetResourceString( 
                        "Argument_BadObjRef"),
                    "Unmarshal"));
            }
 
            // If it is a well known objectRef we need to just connect to
            // the URL inside the objectRef. 
            if (objectRef.IsWellKnown()) 
            {
                obj = Unmarshal( 
                            typeof(System.MarshalByRefObject),
                            objectRef.URI);
                // ensure that we cache the objectRef in the ID
                // this contains type-info and we need it for 
                // validating casts on the wellknown proxy
                // Note: this code path will be relatively rare ... the case 
                // when a well known proxy is passed to a remote call 
                // Otherwise it will be wise to another internal flavor of
                // Unmarshal call that returns the identity as an out param. 
                idObj = IdentityHolder.ResolveIdentity(objectRef.URI);
                if (idObj.ObjectRef == null)
                {
                    idObj.RaceSetObjRef(objectRef); 
                }
                return obj; 
            } 

            Message.DebugOut("RemotingService::InternalUnmarshal IN URI" + objectRef.URI); 
            // Get the identity for the URI
            idObj = IdentityHolder.FindOrCreateIdentity(objectRef.URI, null, objectRef);

            currContext = Thread.CurrentContext; 
            Message.DebugOut("RemotingServices::Unmarshal:  Current context id: " +
                             (currContext.ContextID).ToString("x") + "\n"); 
 
            // If we successfully completed the above method then we should
            // have an identity object 
            BCLDebug.Assert(null != idObj,"null != idObj");


            Message.DebugOut("RemotingService::InternalUnmarshal IN URI" + objectRef.URI); 

            Message.DebugOut("RemotingServices::InternalUnmarshal:  Current context id: " + 
                             (currContext.ContextID).ToString("x") + "\n"); 

 
            // Check whether we are on the server side or client-side
            ServerIdentity serverID = idObj as ServerIdentity;
            if ( serverID != null )
            { 
                Message.DebugOut("RemotingServices::InternalUnmarshal: Unmarshalling ServerIdentity\n");
 
                // SERVER SIDE 
                // We are in the app domain of the server object.
                // If we are in the same context as the server then 
                // just return the server object else return the proxy

                currContext = Thread.CurrentContext;
                Message.DebugOut("RemotingServices::InternalUnmarshal: Current context id: " + 
                                 (currContext.ContextID).ToString("x") + "\n");
                Message.DebugOut("RemotingServices::InternalUnmarshal: ServerContext id: " + 
                                 (serverID.ServerContext.ContextID).ToString("x") + "\n"); 

                if (!serverID.IsContextBound) 
                {
                    BCLDebug.Assert(serverID.ServerType.IsMarshalByRef,
                                    "Object must be at least MarshalByRef in order to be marshaled");
                    if (proxy != null) 
                    {
                        throw new ArgumentException( 
                            String.Format( 
                                CultureInfo.CurrentCulture, Environment.GetResourceString(
                                    "Remoting_BadInternalState_ProxySameAppDomain"))); 
                    }
                    obj = serverID.TPOrObject;
                }
                else 
                {
                        Message.DebugOut("RemotingServices::InternalUnmarshal: Contexts don't match, returning proxy\n"); 
 
                        IMessageSink chnlSink = null;
                        IMessageSink envoySink = null; 

                        // Create the envoy sinks and channel sink
                        CreateEnvoyAndChannelSinks(
                            (MarshalByRefObject)serverID.TPOrObject, 
                            null,
                            out chnlSink, 
                            out envoySink); 

                        // Set the envoy and channel sinks in a thread safe manner 
                        SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);

                        // Get or create the proxy and return
                        obj = GetOrCreateProxy(idObj, proxy, true); 
                    // This will be a TP
                    BCLDebug.Assert(IsTransparentProxy(obj), "Unexpected server"); 
                } 
            }
            else 
            {
                // CLIENT SIDE

                Message.DebugOut("RemotingServices::InternalUnmarshal: Unmarshalling Client-side Identity\n"); 

                IMessageSink chnlSink = null; 
                IMessageSink envoySink = null; 

                // Create the envoy sinks and channel sink 
                if (!objectRef.IsObjRefLite())
                    CreateEnvoyAndChannelSinks(null, objectRef, out chnlSink, out envoySink);
                else
                    CreateEnvoyAndChannelSinks(objectRef.URI, null, out chnlSink, out envoySink); 

                // Set the envoy and channel sinks in a thread safe manner 
                SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink); 

                if (objectRef.HasProxyAttribute()) 
                {
                    fRefine = true;
                }
 
                // Get or create the proxy and return
                obj = GetOrCreateProxy(idObj, proxy, fRefine); 
            } 

            // Notify TrackingServices that we unmarshaled an object 
            TrackingServices.UnmarshaledObject(obj, objectRef);

            // Return the proxy
            Message.DebugOut("RemotingService::InternalUnmarshl OUT \n"); 
            return obj;
 
        } 

       // 
       //
        [System.Security.SecurityCritical]  // auto-generated
        private static Object GetOrCreateProxy(
            Identity idObj, Object proxy, bool fRefine) 
        {
            Message.DebugOut("Entering GetOrCreateProxy for given proxy\n"); 
 
            // If we are not supplied a proxy then we have to find an existing
            // proxy or create one 
            if (null == proxy)
            {
                // Get the type of the server object
                Type serverType; 
                ServerIdentity serverID = idObj as ServerIdentity;
                if (null != serverID) 
                { 
                    serverType = serverID.ServerType; // ServerObject.GetType();
                } 
                else
                {
                    BCLDebug.Assert(ObjRef.IsWellFormed(idObj.ObjectRef),
                                    "ObjRef.IsWellFormed(idObj.ObjectRef)"); 
                    IRemotingTypeInfo serverTypeInfo = idObj.ObjectRef.TypeInfo;
 
                    // For system generated type info we create the proxy for 
                    // object type. Later, when the proxy is cast to the appropriate
                    // type we will update its internal state to refer to the cast type 
                    // This way we avoid loading the server type till cast time.
                    //
                    // For type info generated by others we have no choice but to
                    // load the type provided by the typeinfo. Sometimes, we 
                    // use this second approach even if the typeinfo has been
                    // generated by us because this saves us an extra checkcast. 
                    // A typical example of this usage will be when we are 
                    // unmarshaling in parameters. We know that the unmarshal will
                    // be followed by a check cast to ensure that the parameter type 
                    // matches the signature type, so we do both in one step.
                    serverType = null;
                    if (((serverTypeInfo is TypeInfo) && !fRefine) ||
                        (serverTypeInfo == null)) 
                    {
                        serverType = typeof(System.MarshalByRefObject); 
                    } 
                    else
                    { 
                        String typeName = serverTypeInfo.TypeName;
                        if (typeName != null)
                        {
                            String typeNamespace = null; 
                            String assemNamespace = null;
                            TypeInfo.ParseTypeAndAssembly(typeName, out typeNamespace, out assemNamespace); 
 

                            Assembly assem = FormatterServices.LoadAssemblyFromStringNoThrow(assemNamespace); 

                            if (assem != null)
                            {
                                serverType = assem.GetType(typeNamespace, false, false); 
                            }
 
                        } 

                    } 

                    if (null == serverType)
                    {
                        throw new RemotingException( 
                            String.Format(
                                CultureInfo.CurrentCulture, Environment.GetResourceString( 
                                    "Remoting_BadType"), 
                                serverTypeInfo.TypeName));
                    } 
                }
                Message.DebugOut("Creating Proxy for type " + serverType.FullName + "\n");
                proxy = SetOrCreateProxy(idObj, serverType, null);
            } 
            else
            { 
                // We have been supplied with a proxy. Set that proxy in 
                // the identity object
                // Assert that this the activation case only as this code path is 
                // not thread safe otherwise! (We call Wrap to associate an object
                // with its proxy during activation).
                BCLDebug.Assert(
                    ((RemotingProxy)GetRealProxy(proxy)).ConstructorMessage!=null, 
                    "Only expect to be here during activation!");
                proxy = SetOrCreateProxy(idObj, null, proxy); 
            } 

            // At this point we should have a non-null transparent proxy 
            if (proxy == null)
                throw new RemotingException(Environment.GetResourceString("Remoting_UnexpectedNullTP"));

            BCLDebug.Assert(IsTransparentProxy(proxy),"IsTransparentProxy(proxy)"); 

            Message.DebugOut("Leaving GetOrCreateProxy for given proxy\n"); 
            // Return the underlying transparent proxy 
            return proxy;
        } 

       //
       //
        // This version of GetOrCreateProxy is used for Connect(URI, type) 
        [System.Security.SecurityCritical]  // auto-generated
        private static Object GetOrCreateProxy(Type classToProxy, Identity idObj) 
        { 
            Message.DebugOut("Entering GetOrCreateProxy for given class\n");
 
            Object proxy = idObj.TPOrObject;
            if (null == proxy)
            {
                // Create the  proxy 
                proxy = SetOrCreateProxy(idObj, classToProxy, null);
            } 
            // proxy from idObj may be non-null if we are doing a Connect 
            // under new XXX() ... also if we are connecting to a remote URL
            // which we previously connected. 

            // If we are in the same domain as the server object then we
            // can check for type compatibility of the proxy with the given
            // type. Otherwise, we will defer this check to method call time. 
            // If we do not do this now then we run the risk of returning
            // a proxy which is different from the type given. 
 
            // <
 



 
            ServerIdentity serverID = idObj as ServerIdentity;
            if (null != serverID) 
            { 
                // Check for type compatibility
                Type serverType = serverID.ServerType; 
                if (!classToProxy.IsAssignableFrom(serverType))
                {
                    throw new InvalidCastException(
                        String.Format( 
                            CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "InvalidCast_FromTo"), 
                            serverType.FullName, 
                            classToProxy.FullName));
                } 

            }

            // At this point we should have a non-null transparent proxy 
            BCLDebug.Assert(null != proxy && IsTransparentProxy(proxy),"null != proxy && IsTransparentProxy(proxy)");
 
            Message.DebugOut("Leaving GetOrCreateProxy for given class\n"); 
            return proxy;
        } 


        [System.Security.SecurityCritical]  // auto-generated
        private static MarshalByRefObject SetOrCreateProxy( 
            Identity idObj, Type classToProxy, Object proxy)
 
        { 
            Message.DebugOut("Entering SetOrCreateProxy for type \n");
 
            RealProxy realProxy = null;
            // If a proxy has not been supplied create one
            if (null == proxy)
            { 
                // Create a remoting proxy
                Message.DebugOut("SetOrCreateProxy::Creating Proxy for " + 
                                 classToProxy.FullName + "\n"); 

                ServerIdentity srvID = idObj as ServerIdentity; 
                if (idObj.ObjectRef != null)
                {
                    ProxyAttribute pa = ActivationServices.GetProxyAttribute(classToProxy);
                    realProxy = pa.CreateProxy(idObj.ObjectRef, 
                                           classToProxy,
                                           null,  // 
                                           null); // 
                }
                if(null == realProxy) 
                {
                    // The custom proxy attribute does not want to create a proxy. We create a default
                    // proxy in this case.
                    ProxyAttribute defaultProxyAttribute = ActivationServices.DefaultProxyAttribute; 

                    realProxy = defaultProxyAttribute.CreateProxy(idObj.ObjectRef, 
                                                                  classToProxy, 
                                                                  null,
                                                                  (null == srvID ? null : 
                                                                                   srvID.ServerContext));
                }
            }
            else 
            {
                BCLDebug.Assert(IsTransparentProxy(proxy),"IsTransparentProxy(proxy)"); 
 
                // Extract the remoting proxy from the transparent proxy
                Message.DebugOut("SetOrCreateProxy::Proxy already created \n"); 
                realProxy = GetRealProxy(proxy);
            }

            BCLDebug.Assert(null != realProxy,"null != realProxy"); 

            // Set the back reference to the identity in the proxy object 
            realProxy.IdentityObject = idObj; 

            // Set the reference to the proxy in the identity object 
            proxy = realProxy.GetTransparentProxy();
            proxy = idObj.RaceSetTransparentProxy(proxy);

            Message.DebugOut("Leaving SetOrCreateProxy\n"); 
            // return the transparent proxy
            return (MarshalByRefObject)proxy; 
        } 

        // Check 
        private static bool AreChannelDataElementsNull(Object[] channelData)
        {
            foreach(Object o in channelData)
            { 
                if (o != null)
                    return false; 
            } 

            return true; 

        }

        [System.Security.SecurityCritical]  // auto-generated 
        internal static void CreateEnvoyAndChannelSinks(
            MarshalByRefObject tpOrObject, 
            ObjRef objectRef, 
            out IMessageSink chnlSink,
            out IMessageSink envoySink) 
        {

            Message.DebugOut("Creating envoy and channel sinks \n");
            BCLDebug.Assert( 
                ((null != tpOrObject) || (null != objectRef)),
                "((null != tpOrObject) || (null != objectRef)"); 
 
            // Set the out parameters
            chnlSink = null; 
            envoySink = null;

            if (null == objectRef)
            { 
                // If the objectRef is not present this is a cross context case
                // and we should set the cross context channel sink 
                chnlSink = ChannelServices.GetCrossContextChannelSink(); 

                envoySink = Thread.CurrentContext.CreateEnvoyChain(tpOrObject); 
            }
            else
            {
                // Extract the channel from the channel data and name embedded 
                // inside the objectRef
                Object[] channelData = objectRef.ChannelInfo.ChannelData; 
                if (channelData != null && !AreChannelDataElementsNull(channelData)) 
                {
                    for (int i = 0; i < channelData.Length; i++) 
                    {
                        // Get the first availabe sink
                        chnlSink = ChannelServices.CreateMessageSink(channelData[i]);
                        if (null != chnlSink) 
                        {
                            break; 
                        } 
                    }
 

                    // if chnkSink is still null, try to find a channel that can service
                    //   this uri.
                    if (null == chnlSink) 
                    {
                        // NOTE: careful! we are calling user code here after holding 
                        // the delayLoadChannelLock (channel ctor-s for arbitrary channels 
                        // will run while the lock is held).
                        lock (s_delayLoadChannelLock) 
                        {
                            // Check once to ensure that noone beat us in a ----
                            for (int i = 0; i < channelData.Length; i++)
                            { 
                                // Get the first availabe sink
                                chnlSink = ChannelServices.CreateMessageSink(channelData[i]); 
                                if (null != chnlSink) 
                                {
                                    break; 
                                }
                            }

 
                            if (null == chnlSink)
                            { 
                                // We don't have a sink 
                                foreach (Object data in channelData)
                                { 
                                    String objectURI;
                                    chnlSink =
                                        RemotingConfigHandler.FindDelayLoadChannelForCreateMessageSink(
                                            null, data, out objectURI); 
                                    if (null != chnlSink)
                                        break; 
                                } 
                            }
                        } 
                    }
                }

                // Extract the envoy sinks from the objectRef 
                if ((null != objectRef.EnvoyInfo) &&
                    (null != objectRef.EnvoyInfo.EnvoySinks)) 
                { 
                    envoySink = objectRef.EnvoyInfo.EnvoySinks;
                } 
                else
                {
                    envoySink = EnvoyTerminatorSink.MessageSink;
                } 
            }
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static String CreateEnvoyAndChannelSinks(String url, 
                                                         Object data,
                                                         out IMessageSink chnlSink,
                                                         out IMessageSink envoySink)
        { 
            BCLDebug.Assert(null != url,"null != url");
            String objectURI = null; 
 
            objectURI = CreateChannelSink(url, data, out chnlSink);
 
            envoySink = EnvoyTerminatorSink.MessageSink;

            return objectURI;
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        private static String CreateChannelSink(String url, Object data, out IMessageSink chnlSink) 
        {
            BCLDebug.Assert(null != url,"null != url"); 
            String objectURI = null;

            chnlSink = ChannelServices.CreateMessageSink(url, data, out objectURI);
 
            // if chnkSink is still null, try to find a channel that can service this uri.
            if (null == chnlSink) 
            { 
                lock (s_delayLoadChannelLock)
                { 
                    chnlSink = ChannelServices.CreateMessageSink(url, data, out objectURI);
                    if (null == chnlSink)
                    {
                        chnlSink = 
                            RemotingConfigHandler.FindDelayLoadChannelForCreateMessageSink(
                                url, data, out objectURI); 
                    } 
                }
            } 

            return objectURI;
        } // CreateChannelSinks
 
        internal static void SetEnvoyAndChannelSinks(Identity idObj,
                                                    IMessageSink chnlSink, 
                                                    IMessageSink envoySink) 
        {
            Message.DebugOut("Setting up envoy and channel sinks \n"); 
            BCLDebug.Assert(null != idObj,"null != idObj");

            // Decide if we need to set the envoy sink chain
            if (null == idObj.ChannelSink) 
            {
                if (null != chnlSink) 
                { 
                    idObj.RaceSetChannelSink(chnlSink);
                } 
            }

            // Decide if we need to set the envoy sink chain
            if (null == idObj.EnvoyChain) 
            {
                if (null != envoySink) 
                { 
                    idObj.RaceSetEnvoyChain(envoySink);
                } 
                else
                {
                    throw new RemotingException(
                        String.Format( 
                            CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "Remoting_BadInternalState_FailEnvoySink"))); 
                } 
            }
        } 

        // Check whether the transparent proxy backing the real proxy
        // is assignable from the given type.
        [System.Security.SecurityCritical]  // auto-generated 
        private static bool CheckCast(RealProxy rp, RuntimeType castType)
        { 
            // NOTE: This is the point where JIT_CheckCastClass ultimately 
            // lands up in the managed world if the object being cast is
            // a transparent proxy. 
            // If we are here, it means that walking the current EEClass
            // up the chain inside the EE was unable to verify the cast.

            Message.DebugOut("Entered CheckCast for type " + castType); 
            bool fCastOK = false;
 
            BCLDebug.Assert(rp != null, "Shouldn't be called with null real proxy."); 

            // Always return true if cast is to System.Object 
            if (castType == typeof(Object))
                return true;

            // We do not allow casting to non-interface types that do not extend 
            // from System.MarshalByRefObject
            if (!castType.IsInterface && !castType.IsMarshalByRef) 
                return false; 

            // Note: this is a bit of a hack to allow deserialization of WellKnown 
            // object refs (in the well known cases, we always return TRUE for
            // interface casts but doing so messes us up in the case when
            // the object manager is trying to resolve object references since
            // it ends up thinking that the proxy we returned needs to be resolved 
            // further).
            if (castType != typeof(IObjectReference)) 
            { 
                IRemotingTypeInfo typeInfo = rp as IRemotingTypeInfo;
                if(null != typeInfo) 
                {
                    fCastOK = typeInfo.CanCastTo(castType, rp.GetTransparentProxy());
                }
                else 
                {
                    // The proxy does not implement IRemotingTypeInfo, so we should 
                    //   try to do casting based on the ObjRef type info. 
                    Identity id = rp.IdentityObject;
                    if (id != null) 
                    {
                        ObjRef objRef = id.ObjectRef;
                        if (objRef != null)
                        { 
                            typeInfo = objRef.TypeInfo;
                            if (typeInfo != null) 
                            { 
                                fCastOK = typeInfo.CanCastTo(castType, rp.GetTransparentProxy());
                            } 
                        }
                    }
                }
            } 

            Message.DebugOut("CheckCast returning " + fCastOK); 
            return fCastOK; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static bool ProxyCheckCast(RealProxy rp, RuntimeType castType)
        {
            return CheckCast(rp, castType); 
        } // ProxyCheckCast
 
        /* 
        **CheckCast
        **Action:  When a proxy to an object is serialized, the MethodTable is only 
        **         expanded on an on-demand basis.  For purely managed operations, this
        **         happens in a transparent fashion.  However, for delegates (and
        **         potentially other types) we need to force this expansion to happen.
        **Returns: The newly expanded object.  Returns the identity if no expansion is required. 
        **Arguments: objToExpand -- The object to be expanded.
        **           type -- the type to which to expand it. 
        **Exceptions: None. 
        */
        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern Object CheckCast(Object objToExpand, RuntimeType type);
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static GCHandle CreateDelegateInvocation(WaitCallback waitDelegate, Object state) 
        { 
            Object[] delegateCallToken = new Object[2];
            delegateCallToken[0] = waitDelegate; 
            delegateCallToken[1] = state;
            return System.Runtime.InteropServices.GCHandle.Alloc(delegateCallToken);
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static void DisposeDelegateInvocation(GCHandle delegateCallToken) 
        { 
            delegateCallToken.Free();
        } 

        [System.Security.SecurityCritical]  // auto-generated
        internal static Object CreateProxyForDomain(int appDomainId, IntPtr defCtxID)
        { 
            AppDomain proxy = null;
 
            ObjRef objRef = CreateDataForDomain(appDomainId, defCtxID); 

            // Unmarshal the objref in the old app domain 
            proxy = (AppDomain)Unmarshal(objRef);

            return proxy;
        } // CreateProxyForDomain 

        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object CreateDataForDomainCallback(Object[] args) 
        {
            // Ensure that the well known channels are registered in this domain too 
            RegisterWellKnownChannels();

            // Marshal the app domain object
            ObjRef objref = MarshalInternal( 
                           Thread.CurrentContext.AppDomain,
                            null, 
                            null, 
                            false);
 
            ServerIdentity si = (ServerIdentity)MarshalByRefObject.GetIdentity(Thread.CurrentContext.AppDomain);
            si.SetHandle();
            objref.SetServerIdentity(si.GetHandle());
            objref.SetDomainID(AppDomain.CurrentDomain.GetId()); 
            return objref;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static ObjRef CreateDataForDomain(int appDomainId, IntPtr defCtxID) 
        {
            // This is a subroutine of CreateProxyForDomain
            // so we can segregate the object references
            // from different app domains into different frames.  This is 
            // important for the app domain leak checking code.
 
            Message.DebugOut("Creating proxy for domain " + appDomainId + "\n"); 

            RegisterWellKnownChannels(); 

            InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(CreateDataForDomainCallback);

            return (ObjRef) Thread.CurrentThread.InternalCrossContextCallback(null, defCtxID, appDomainId, xctxDel, null); 

        } // CreateDataForDomain 
 

        [System.Security.SecurityCritical]  // auto-generated_required 
        public static MethodBase GetMethodBaseFromMethodMessage(IMethodMessage msg)
        {
            MethodBase mb = InternalGetMethodBaseFromMethodMessage(msg);
            return mb; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static MethodBase InternalGetMethodBaseFromMethodMessage(IMethodMessage msg)
        { 
            if(null == msg)
            {
                return null;
            } 

            Type t = RemotingServices.InternalGetTypeFromQualifiedTypeName(msg.TypeName); 
            if (t == null) 
            {
                throw new RemotingException( 
                    String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString(
                            "Remoting_BadType"),
                        msg.TypeName)); 

            } 
 
            // Use the signature, type and method name to determine the
            // methodbase via reflection. 
            Type[] signature = (Type[])msg.MethodSignature;
            return GetMethodBase(msg, t, signature);
        }
 
        [System.Security.SecurityCritical]  // auto-generated_required
        public static bool IsMethodOverloaded(IMethodMessage msg) 
        { 
            RemotingMethodCachedData cache =
                InternalRemotingServices.GetReflectionCachedData(msg.MethodBase); 

            return cache.IsOverloaded();
        } // IsMethodOverloaded
 

        [System.Security.SecurityCritical]  // auto-generated 
        private static MethodBase GetMethodBase(IMethodMessage msg, Type t, Type[] signature) 
        {
            MethodBase mb = null; 

            // Get the reflection object depending on whether it is a
            // constructor call or a method call.
            if((msg is IConstructionCallMessage) || 
               (msg is IConstructionReturnMessage))
            { 
                if((null == signature)) 
                {
                    BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with null sig ", msg.MethodName); 
                    ConstructorInfo[] ci;
                    RuntimeType rt = t as RuntimeType;
                    if (rt == null)
                        ci = t.GetConstructors(); 
                    else
                        ci = rt.GetConstructors(); 
 
                    if(1 != ci.Length)
                    { 
                        // There is more than one constructor defined but
                        // we do not have a signature to differentiate between
                        // them.
                                throw new AmbiguousMatchException( 
                                    Environment.GetResourceString(
                                        "Remoting_AmbiguousCTOR")); 
                    } 
                    mb = ci[0];
                } 
                else
                {
                    BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg.MethodName, " ", signature.Length);
                    RuntimeType rt = t as RuntimeType; 
                    if (rt == null)
                        mb = t.GetConstructor(signature); 
                    else 
                        mb = rt.GetConstructor(signature);
                } 
            }
            else if((msg is IMethodCallMessage) || (msg is IMethodReturnMessage))
            {
                // We demand reflection permission in the api that calls this 
                // for non-public types
                if(null == signature) 
                { 
                    BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with null sig ", msg.MethodName);
                    RuntimeType rt = t as RuntimeType; 
                    if (rt == null)
                        mb = t.GetMethod(msg.MethodName, RemotingServices.LookupAll);
                    else
                        mb = rt.GetMethod(msg.MethodName, RemotingServices.LookupAll); 
                }
                else 
                { 
                    BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg.MethodName, " ", signature.Length);
                    RuntimeType rt = t as RuntimeType; 
                    if (rt == null)
                        mb = t.GetMethod(msg.MethodName, RemotingServices.LookupAll, null, signature, null);
                    else
                        mb = rt.GetMethod(msg.MethodName, RemotingServices.LookupAll, null, CallingConventions.Any, signature, null); 
                }
 
            } 

            return mb; 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal static bool IsMethodAllowedRemotely(MethodBase method) 
        {
            // MarhsalByRefObject.InvokeMember is allowed to be invoked remotely. It is a wrapper for a com method as represented in managed 
            // code. The managed code was generated by tlbimpl. A test does not have to be made to make sure that the COM object method is public because 
            // the tlbimpl will only generate methods which can be invoked remotely.
 
            if (s_FieldGetterMB == null ||
                s_FieldSetterMB == null ||
                s_IsInstanceOfTypeMB == null ||
                s_InvokeMemberMB == null || 
                s_CanCastToXmlTypeMB == null)
            { 
                System.Security.CodeAccessPermission.Assert(true); 
                if (s_FieldGetterMB == null)
                    s_FieldGetterMB = typeof(Object).GetMethod(FieldGetterName,RemotingServices.LookupAll); 

                if (s_FieldSetterMB == null)
                    s_FieldSetterMB = typeof(Object).GetMethod(FieldSetterName, RemotingServices.LookupAll);
 
                if (s_IsInstanceOfTypeMB == null)
                { 
                    s_IsInstanceOfTypeMB = 
                        typeof(MarshalByRefObject).GetMethod(
                            IsInstanceOfTypeName, RemotingServices.LookupAll); 
                }

                if (s_CanCastToXmlTypeMB == null)
                { 
                    s_CanCastToXmlTypeMB =
                        typeof(MarshalByRefObject).GetMethod( 
                            CanCastToXmlTypeName, RemotingServices.LookupAll); 
                }
 
                if (s_InvokeMemberMB == null)
                {
                    s_InvokeMemberMB =
                        typeof(MarshalByRefObject).GetMethod( 
                            InvokeMemberName, RemotingServices.LookupAll);
                } 
            } 

            return 
                method == s_FieldGetterMB ||
                method == s_FieldSetterMB ||
                method == s_IsInstanceOfTypeMB ||
                method == s_InvokeMemberMB || 
                method == s_CanCastToXmlTypeMB;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated_required
        public static bool IsOneWay(MethodBase method) 
        {
            if (method == null)
                return false;
 
            RemotingMethodCachedData cache =
                InternalRemotingServices.GetReflectionCachedData(method); 
 
            return cache.IsOneWayMethod();
        } 

        // Given a method base object, see if we can find an async version of the
        //   method on the same class.
        internal static bool FindAsyncMethodVersion(MethodInfo method, 
                                                    out MethodInfo beginMethod,
                                                    out MethodInfo endMethod) 
        { 
            beginMethod = null;
            endMethod = null; 

            // determine names of Begin/End versions
            String beginName = "Begin" + method.Name;
            String endName = "End" + method.Name; 

            // determine parameter lists for Begin/End versions 
            ArrayList beginParameters = new ArrayList(); 
            ArrayList endParameters = new ArrayList();
 
            Type beginReturnType = typeof(IAsyncResult);
            Type endReturnType = method.ReturnType;

            ParameterInfo[] paramList = method.GetParameters(); 
            foreach (ParameterInfo param in paramList)
            { 
                if (param.IsOut) 
                    endParameters.Add(param);
                else 
                if (param.ParameterType.IsByRef)
                {
                    beginParameters.Add(param);
                    endParameters.Add(param); 
                }
                else 
                { 
                    // it's an in parameter
                    beginParameters.Add(param); 
                }
            }

            beginParameters.Add(typeof(AsyncCallback)); 
            beginParameters.Add(typeof(Object));
            endParameters.Add(typeof(IAsyncResult)); 
 
            // try to match these signatures with the methods on the type
            Type type = method.DeclaringType; 
            MethodInfo[] methods = type.GetMethods();

            foreach (MethodInfo mi in methods)
            { 
                ParameterInfo[] parameterList = mi.GetParameters();
 
                // see if return value is IAsyncResult 
                if (mi.Name.Equals(beginName) &&
                    (mi.ReturnType == beginReturnType) && 
                    CompareParameterList(beginParameters, parameterList))

                {
                    beginMethod = mi; 
                }
                else 
                if (mi.Name.Equals(endName) && 
                    (mi.ReturnType == endReturnType) &&
                    CompareParameterList(endParameters, parameterList)) 
                {
                    endMethod = mi;
                }
            } 

            if ((beginMethod != null) && (endMethod != null)) 
                return true; 
            else
                return false; 
        } // FindAsyncMethodVersion


        // Helper function for FindAsyncMethodVersion 
        private static bool CompareParameterList(ArrayList params1, ParameterInfo[] params2)
        { 
            // params1 contains a list of parameters (and possibly some types which are 
            //   assumed to be in parameters)
            // param2 just contains the list of parameters from some method 

            if (params1.Count != params2.Length)
                return false;
 
            int co = 0;
            foreach (Object obj in params1) 
            { 
                ParameterInfo param = params2[co];
 
                ParameterInfo pi = obj as ParameterInfo;
                if (null != pi)
                {
                    if ((pi.ParameterType != param.ParameterType) || 
                        (pi.IsIn != param.IsIn) ||
                        (pi.IsOut != param.IsOut)) 
                    { 
                        return false;
                    } 
                }
                else
                if (((Type)obj != param.ParameterType) && param.IsIn)
                    return false; 
                co++;
            } 
 
            return true;
        } // CompareParameterList 


        [System.Security.SecurityCritical]  // auto-generated_required
        public static Type GetServerTypeForUri(String URI) 
        {
            Type svrType = null; 
 
            if(null != URI)
            { 
                ServerIdentity srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI);

                if(null == srvID)
                { 
                    // Check if this a well-known object which needs to be faulted in
                    svrType = RemotingConfigHandler.GetServerTypeForUri(URI); 
                } 
                else
                { 
                    svrType = srvID.ServerType;
                }
            }
 
            return svrType;
        } 
 

        // This method is called after an appdomain is unloaded from the 
        // current domain.
        [System.Security.SecurityCritical]  // auto-generated
        internal static void DomainUnloaded(Int32 domainID)
        { 
            // Remove any client side identities, presumably the driver
            // domain has released all references to proxies in the unloaded 
            // domain. 
            IdentityHolder.FlushIdentityTable();
            // Remove the cross domain channel sink for the unloaded domain 
            CrossAppDomainSink.DomainUnloaded(domainID);
        }

        //  This method is called from the VM and helps the appdomain 
        //  folks to get to the server appdomain from a proxy. This is
        //  expected to be called on strictly cross domain proxies. 
        // 
        //  This returns the unmanaged context object for the proxy.
        //  We fetch the appDomain out of the context in the VM. 
        // This will return NULL (or 0) if the server for the proxy is
        // not from this process or if the server domain is invalid
        // or if there is not enough information to determine the server
        // context. 
        [System.Security.SecurityCritical]  // auto-generated
        internal static IntPtr GetServerContextForProxy(Object tp) 
        { 
            ObjRef objRef = null;
            bool bSameDomain; 
            int domainId;
            return GetServerContextForProxy(
                        tp,
                        out objRef, 
                        out bSameDomain,
                        out domainId); 
        } 

        // This returns the domain ID if the proxy is from this process 
        // whether or not the domain is valid!
        [System.Security.SecurityCritical]  // auto-generated
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        internal static int GetServerDomainIdForProxy(Object tp) 
        {
            Contract.Assert(IsTransparentProxy(tp),"Must be called only for TPs"); 
            RealProxy rp=GetRealProxy(tp); 
            Identity id = rp.IdentityObject;
            return id.ObjectRef.GetServerDomainId(); 

        }

        // This will retrieve the server domain and context id 
        [System.Security.SecurityCritical]  // auto-generated
        internal static void GetServerContextAndDomainIdForProxy(Object tp, 
                                                                 out IntPtr contextId, 
                                                                 out int domainId)
        { 
            ObjRef objRef;
            bool bSameDomain;
            contextId =
                GetServerContextForProxy( 
                    tp,
                    out objRef, 
                    out bSameDomain, 
                    out domainId);
        } // GetServerContextAndDomainIdForProxy 


        // This is a helper for the methods above.
        // NOTE:: Returns the unmanaged server context for a proxy 
        // This is *NOT* the same as "public int Context::ContextID"
        [System.Security.SecurityCritical]  // auto-generated 
        private static IntPtr GetServerContextForProxy( 
            Object tp, out ObjRef objRef, out bool bSameDomain, out int domainId)
        { 
            // Note: the contextId we return from here should be the address
            // of the unmanaged (VM) context object or NULL.

            IntPtr contextId = IntPtr.Zero; 
            objRef = null;
            bSameDomain = false; 
            domainId = 0; 
            if (IsTransparentProxy(tp))
            { 
                // This is a transparent proxy. Try to obtain the backing
                // RealProxy from it.
                RealProxy rp = GetRealProxy(tp);
 
                // Get the identity from the realproxy
                Identity id = rp.IdentityObject; 
                if(null != id) 
                {
                    ServerIdentity serverID = id as ServerIdentity; 
                    if (null != serverID)
                    {
                        // We are in the app domain of the server
                        bSameDomain = true; 
                        contextId = serverID.ServerContext.InternalContextID;
                        domainId = Thread.GetDomain().GetId(); 
                    } 
                    else
                    { 
                        // Server is from another app domain
                        // (possibly from another process)
                        objRef = id.ObjectRef;
                        if (objRef != null) 
                        {
                            contextId = objRef.GetServerContext(out domainId); 
                        } 
                        else
                        { 
                            // Proxy does not have an associated ObjRef
                            // <

 

                            //Contract.Assert(false, "Found proxy without an objref"); 
                            contextId = IntPtr.Zero; 
                        }
                    } 
                }
                else
                {
                    // This was probably a custom proxy other than RemotingProxy 
                    Contract.Assert(
                        !(rp is RemotingProxy), 
                        "!(rp is RemotingProxy)"); 

                    contextId = Context.DefaultContext.InternalContextID; 
                }
            }

            return contextId; 
        }
 
       //   Return the server context of the object provided if the object 
       //   was born in the current appdomain, else return null.
       // 
        // NOTE: This returns the managed context object that the server
        // is associated with ...
        // <
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static Context GetServerContext(MarshalByRefObject obj) 
        { 
            Context serverCtx = null;
 
            if(!IsTransparentProxy(obj) && (obj is ContextBoundObject))
            {
                // The object is native to the current context.
                serverCtx = Thread.CurrentContext; 
            }
            else 
            { 
                RealProxy rp = GetRealProxy(obj);
                Identity id = rp.IdentityObject; 
                ServerIdentity serverID = id as ServerIdentity;
                if(null != serverID)
                {
                    // The object was born in the current appdomain. 
                    // Extract the server context.
                    serverCtx = serverID.ServerContext; 
                } 
            }
 
            return serverCtx;
        }

       //   Return the actual type of the server object given the proxy 
       //
       // 
        [System.Security.SecurityCritical]  // auto-generated 
        private static Object GetType(Object tp)
        { 
            Contract.Assert(IsTransparentProxy(tp), "IsTransparentProxy(tp)");

            Type serverType = null;
 
            RealProxy rp = GetRealProxy(tp);
            Identity id = rp.IdentityObject; 
            Contract.Assert(!(id is ServerIdentity), "(!id is ServerIdentity)"); 
            if((null != id) && (null != id.ObjectRef) &&
               (null != id.ObjectRef.TypeInfo)) 
            {
                IRemotingTypeInfo serverTypeInfo = id.ObjectRef.TypeInfo;
                String typeName = serverTypeInfo.TypeName;
                if (typeName != null) 
                {
                    serverType = InternalGetTypeFromQualifiedTypeName(typeName); 
                } 
            }
 
            return serverType;
        }

 
        [System.Security.SecurityCritical]  // auto-generated
        internal static byte[] MarshalToBuffer(Object o, bool crossRuntime) 
        { 
            if (crossRuntime)
            { 
                // Making a call on a MBRO cross-process or cross-runtime likely fails in most common
                // scenarios. We check for signs that Remoting is really expected by the user.
                if (RemotingServices.IsTransparentProxy(o))
                { 
                    if (RemotingServices.GetRealProxy(o) is RemotingProxy)
                    { 
                        // the object uses a default proxy - it means that Remoting may not be expected 
                        if (ChannelServices.RegisteredChannels.Length == 0)
                        { 
                            return null;
                        }
                    }
                } 
                else
                { 
                    MarshalByRefObject mbro = o as MarshalByRefObject; 
                    if (mbro != null)
                    { 
                        ProxyAttribute proxyAttr = ActivationServices.GetProxyAttribute(mbro.GetType());
                        if (proxyAttr == ActivationServices.DefaultProxyAttribute)
                        {
                            // the object does not use a custom proxy - it means that Remoting may not be expected 
                            if (ChannelServices.RegisteredChannels.Length == 0)
                            { 
                                return null; 
                            }
                        } 
                    }
                }
            }
 
            // serialize headers and args together using the binary formatter
            MemoryStream stm = new MemoryStream(); 
            RemotingSurrogateSelector ss = new RemotingSurrogateSelector(); 
            BinaryFormatter fmt = new BinaryFormatter();
            fmt.SurrogateSelector = ss; 
            fmt.Context = new StreamingContext(StreamingContextStates.Other);
            fmt.Serialize(stm, o, null, false /* No Security check */);

            return stm.GetBuffer(); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object UnmarshalFromBuffer(byte [] b, bool crossRuntime)
        { 
            MemoryStream stm = new MemoryStream(b);
            BinaryFormatter fmt = new BinaryFormatter();
            fmt.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; //*******Add this line
            fmt.SurrogateSelector = null; 
            fmt.Context = new StreamingContext(StreamingContextStates.Other);
            Object o = fmt.Deserialize(stm, null, false /* No Security check */); 
 
            if (crossRuntime && RemotingServices.IsTransparentProxy(o))
            { 
                // Making a call on a MBRO cross-process or cross-runtime likely fails in most common
                // scenarios. We check for signs that Remoting is really expected by the user.
                if (!(RemotingServices.GetRealProxy(o) is RemotingProxy))
                { 
                    // the object uses a non-default proxy - this means that Remoting is expected
                    return o; 
                } 

                if (ChannelServices.RegisteredChannels.Length == 0) 
                {
                    // the object uses the default Remoting proxy but there are no channels registered
                    return null;
                } 

                // make a dummy call on the proxy and if it passes use Remoting (the caller of this method 
                // catches exceptions and interprets them as fallback to COM) 
                o.GetHashCode();
            } 

            return o;
        }
 
        internal static Object UnmarshalReturnMessageFromBuffer(byte [] b, IMethodCallMessage msg)
        { 
            MemoryStream stm = new MemoryStream(b); 
            BinaryFormatter fmt = new BinaryFormatter();
            fmt.SurrogateSelector = null; 
            fmt.Context = new StreamingContext(StreamingContextStates.Other);
            Object o = fmt.DeserializeMethodResponse(stm, null, (IMethodCallMessage)msg);
             //= fmt.Deserialize(stm, null, false /* No Security check */);
            return o; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated_required 
        public static IMethodReturnMessage ExecuteMessage(MarshalByRefObject target,
                                                          IMethodCallMessage reqMsg) 
        {
            // Argument validation
            if(null == target)
            { 
                throw new ArgumentNullException("target");
            } 
            Contract.EndContractBlock(); 

            RealProxy rp = GetRealProxy(target); 

            // Check for context match
            if( rp is RemotingProxy
                &&  !rp.DoContextsMatch() ) 
            {
                throw new RemotingException( 
                    Environment.GetResourceString("Remoting_Proxy_WrongContext")); 
            }
 
            // Dispatch the message
            StackBuilderSink dispatcher = new StackBuilderSink(target);

            // dispatch the message 
            IMethodReturnMessage retMsg = (IMethodReturnMessage)dispatcher.SyncProcessMessage(reqMsg, 0, true);
 
            return retMsg; 
        } // ExecuteMessage
 


        //
        // Methods for mapping and resolving qualified type names 
        //   A qualified type name describes the name that we use in the ObjRef and
        //   message TypeName. It consists either of the actual type name or 
        //   ":typename" where for now "soap:" is the only 
        //   supported alternative.  In the future, we may make this type resolution
        //   extensible and publicly exposed. 
        //

        // This is used by the cached type data to figure out which type name
        //   to use (this should never be publicly exposed; GetDefaultQualifiedTypeName should, 
        //   if anything at all)
        [System.Security.SecurityCritical]  // auto-generated 
        internal static String DetermineDefaultQualifiedTypeName(Type type) 
        {
            if (type == null) 
                throw new ArgumentNullException("type");
            Contract.EndContractBlock();

            // see if there is an xml type name 
            String xmlTypeName = null;
            String xmlTypeNamespace = null; 
            if (SoapServices.GetXmlTypeForInteropType(type, out xmlTypeName, out xmlTypeNamespace)) 
            {
                return "soap:" + xmlTypeName + ", " + xmlTypeNamespace; 
            }

            // there are no special mappings, so use the fully qualified CLR type name
            // < 
            return type.AssemblyQualifiedName;
        } // DetermineDefaultQualifiedTypeName 
 

        // retrieves type name from the cache data which uses DetermineDefaultQualifiedTypeName 
        [System.Security.SecurityCritical]  // auto-generated
        internal static String GetDefaultQualifiedTypeName(RuntimeType type)
        {
            RemotingTypeCachedData cache = (RemotingTypeCachedData) 
                InternalRemotingServices.GetReflectionCachedData(type);
 
            return cache.QualifiedTypeName; 
        } // GetDefaultQualifiedTypeName
 

        internal static String InternalGetClrTypeNameFromQualifiedTypeName(String qualifiedTypeName)
        {
            // look to see if this is a clr type name 
            if (qualifiedTypeName.Length > 4) // length of "clr:"
            { 
                if (String.CompareOrdinal(qualifiedTypeName, 0, "clr:", 0, 4) == 0) 
                {
                    // strip "clr:" off the front 
                    String actualTypeName = qualifiedTypeName.Substring(4);
                    return actualTypeName;
                }
            } 
            return null;
        } 
 
        private static int IsSoapType(String qualifiedTypeName)
        { 
            // look to see if this is a soap type name
            if (qualifiedTypeName.Length > 5) // length of "soap:"
            {
                if (String.CompareOrdinal(qualifiedTypeName, 0, "soap:", 0, 5) == 0) 
                {
                    // find comma starting from just past "soap:" 
                    return qualifiedTypeName.IndexOf(',', 5); 
                }
            } 
            return -1;
        }

        [System.Security.SecurityCritical]  // auto-generated 
        internal static String InternalGetSoapTypeNameFromQualifiedTypeName(String xmlTypeName, String xmlTypeNamespace)
        { 
            // This must be the default encoding of the soap type (or the type wasn't 
            //   preloaded).
            String typeNamespace; 
            String assemblyName;
            if (!SoapServices.DecodeXmlNamespaceForClrTypeNamespace(
                    xmlTypeNamespace,
                    out typeNamespace, out assemblyName)) 
            {
                return null; 
            } 

            String typeName; 
            if ((typeNamespace != null) && (typeNamespace.Length > 0))
                typeName = typeNamespace + "." + xmlTypeName;
            else
                typeName = xmlTypeName; 

            try 
            { 
                String fullTypeName = typeName + ", " + assemblyName;
                return fullTypeName; 
            }
            catch
            {
                // We ignore errors and will just return null below since the type 
                //   isn't set.
            } 
            return null; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static String InternalGetTypeNameFromQualifiedTypeName(String qualifiedTypeName)
        {
            if (qualifiedTypeName == null) 
                throw new ArgumentNullException("qualifiedTypeName");
            Contract.EndContractBlock(); 
 
            String decodedName = InternalGetClrTypeNameFromQualifiedTypeName(qualifiedTypeName);
            if (decodedName != null) 
            {
                return decodedName;
            }
            int index = IsSoapType(qualifiedTypeName); 
            if (index != -1)
            { 
                // This is a soap type name. We need to parse it and try to 
                //   find the actual type. Format is "soap:xmlTypeName, xmlTypeNamespace"
 
                String xmlTypeName = qualifiedTypeName.Substring(5, index - 5);
                // +2 is to skip the comma and following space
                String xmlTypeNamespace =
                    qualifiedTypeName.Substring(index + 2, qualifiedTypeName.Length - (index + 2)); 

                decodedName = InternalGetSoapTypeNameFromQualifiedTypeName(xmlTypeName, xmlTypeNamespace); 
                if (decodedName != null) 
                {
                    return decodedName; 
                }
            }
            //no prefix return same
            return qualifiedTypeName; 

        } 
 
        // Retrieves type based on qualified type names. This does not do security checks
        // so don't expose this publicly (at least not directly). It returns null if the 
        // type cannot be loaded.
        [System.Security.SecurityCritical]  // auto-generated
        internal static RuntimeType InternalGetTypeFromQualifiedTypeName(String qualifiedTypeName, bool partialFallback)
        { 
            if (qualifiedTypeName == null)
                throw new ArgumentNullException("qualifiedTypeName"); 
            Contract.EndContractBlock(); 

            String decodedName = InternalGetClrTypeNameFromQualifiedTypeName(qualifiedTypeName); 
            if (decodedName != null)
            {
                return LoadClrTypeWithPartialBindFallback(decodedName, partialFallback);
            } 

            int index = IsSoapType(qualifiedTypeName); 
            if (index != -1) 
            {
                // This is a soap type name. We need to parse it and try to 
                //   find the actual type. Format is "soap:xmlTypeName, xmlTypeNamespace"

                String xmlTypeName = qualifiedTypeName.Substring(5, index - 5);
                // +2 is to skip the comma and following space 
                String xmlTypeNamespace =
                    qualifiedTypeName.Substring(index + 2, qualifiedTypeName.Length - (index + 2)); 
 
                RuntimeType type = (RuntimeType)SoapServices.GetInteropTypeFromXmlType(xmlTypeName, xmlTypeNamespace);
                if (type != null) 
                {
                    return type;
                }
                decodedName = InternalGetSoapTypeNameFromQualifiedTypeName(xmlTypeName, xmlTypeNamespace); 
                if (decodedName != null)
                { 
                    return LoadClrTypeWithPartialBindFallback(decodedName, true); 
                }
            } 

            // There is no prefix, so assume this is a normal CLR type name.
            return LoadClrTypeWithPartialBindFallback(qualifiedTypeName, partialFallback);
        } // InternalGetTypeFromQualifiedTypeName 

        [System.Security.SecurityCritical]  // auto-generated 
        internal static Type InternalGetTypeFromQualifiedTypeName(String qualifiedTypeName) 
        {
            return InternalGetTypeFromQualifiedTypeName(qualifiedTypeName, true); 
        }

        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        private unsafe static RuntimeType LoadClrTypeWithPartialBindFallback(String typeName, bool partialFallback) 
        {
            // Try to load a type with fully qualified name if partialFallback is not requested 
            if (!partialFallback) 
            {
                return (RuntimeType)Type.GetType(typeName, false); 
            }
            else
            {
                // A hack 
                StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
                return RuntimeTypeHandle.GetTypeByName(typeName, false, false, false, ref stackMark, true /* hack */); 
            } 
        } // LoadClrTypeWithPartialBindFallback
 
        //
        // end of Methods for mapping and resolving qualified type names
        //
 

        // 
        // These are used by the profiling code to profile remoting. 
        //
        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern bool CORProfilerTrackRemoting();
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        internal static extern bool CORProfilerTrackRemotingCookie();
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern bool CORProfilerTrackRemotingAsync(); 

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern void CORProfilerRemotingClientSendingMessage(out Guid id, bool fIsAsync); 

        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        internal static extern void CORProfilerRemotingClientReceivingReply(Guid id, bool fIsAsync);
 
        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        internal static extern void CORProfilerRemotingServerReceivingMessage(Guid id, bool fIsAsync);

        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern void CORProfilerRemotingServerSendingReply(out Guid id, bool fIsAsync); 
 
        [System.Security.SecurityCritical]  // auto-generated_required
        [System.Diagnostics.Conditional("REMOTING_PERF")] 
        [Obsolete("Use of this method is not recommended. The LogRemotingStage existed for internal diagnostic purposes only.")]
        public static void LogRemotingStage(int stage) {}

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        internal static extern void ResetInterfaceCache(Object proxy); 

    } // RemotingServices 


    [System.Security.SecurityCritical]  // auto-generated_required
    [System.Runtime.InteropServices.ComVisible(true)] 
    public class InternalRemotingServices
    { 
 
        [System.Security.SecurityCritical]  // auto-generated
        [System.Diagnostics.Conditional("_LOGGING")] 
        public static void DebugOutChnl(String s)
        {
            // BCLDebug.Trace("REMOTINGCHANNELS", "CHNL:" + s + "\n");
            Message.OutToUnmanagedDebugger("CHNL:"+s+"\n"); 
            // Console.WriteLine("CHNL:"+s+"\n");
        } 
 

        [System.Diagnostics.Conditional("_LOGGING")] 
        public static void RemotingTrace(params Object[]messages)
        {
                BCLDebug.Trace("REMOTINGCHANNELS",messages);
        } 

 
        [System.Diagnostics.Conditional("_DEBUG")] 
        public static void RemotingAssert(bool condition, String message)
        { 
                Contract.Assert(condition, message);
        }

 
        [System.Security.SecurityCritical]  // auto-generated
        [CLSCompliant(false)] 
        public static void SetServerIdentity(MethodCall m, Object srvID) 
        {
            IInternalMessage im = (IInternalMessage) m; 
            im.ServerIdentityObject = (ServerIdentity)srvID;
        }

 
        // access attribute cached on the reflection object
        internal static RemotingMethodCachedData GetReflectionCachedData(MethodBase mi) 
        { 
            RemotingMethodCachedData cache = null;
 
            RuntimeMethodInfo rmi = null;
            RuntimeConstructorInfo rci = null;

            if ((rmi = mi as RuntimeMethodInfo) != null) 
            {
                cache = (RemotingMethodCachedData)rmi.RemotingCache[CacheObjType.RemotingData]; 
                if (cache == null) 
                    rmi.RemotingCache[CacheObjType.RemotingData] = cache = new RemotingMethodCachedData(rmi);
            } 
            else if ((rci = mi as RuntimeConstructorInfo) != null)
            {
                cache = (RemotingMethodCachedData)rci.RemotingCache[CacheObjType.RemotingData];
                if (cache == null) 
                    rci.RemotingCache[CacheObjType.RemotingData] = cache = new RemotingMethodCachedData(rci);
            } 
            else 
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
 
            return cache;
        }// GetCachedRemotingAttribute

        internal static RemotingTypeCachedData GetReflectionCachedData(RuntimeType mi) 
        {
            RemotingTypeCachedData cache = null; 
            cache = (RemotingTypeCachedData)mi.RemotingCache[CacheObjType.RemotingData]; 
            if (cache == null)
            { 
                cache = new RemotingTypeCachedData(mi);
                mi.RemotingCache[CacheObjType.RemotingData] = cache;
            }
            return cache; 
        }// GetCachedRemotingAttribute
 
        internal static RemotingCachedData GetReflectionCachedData(MemberInfo mi) 
        {
            RemotingCachedData cache = null; 

            MethodBase mb = null;
            RuntimeType rt = null;
            RuntimeFieldInfo rfi = null; 
            RuntimeEventInfo rei = null;
            RuntimePropertyInfo rpi = null; 
            SerializationFieldInfo sfi = null; 

            if ((mb = mi as MethodBase) != null) 
                return GetReflectionCachedData(mb);
            else if ((rt = mi as RuntimeType) != null)
                return GetReflectionCachedData(rt);
            else if ((rfi = mi as RuntimeFieldInfo) != null) 
            {
                cache = (RemotingCachedData)rfi.RemotingCache[CacheObjType.RemotingData]; 
                if (cache == null) 
                    rfi.RemotingCache[CacheObjType.RemotingData] = cache = new RemotingCachedData(rfi);
            } 
            else if ((rei = mi as RuntimeEventInfo) != null)
            {
                cache = (RemotingCachedData)rei.RemotingCache[CacheObjType.RemotingData];
                if (cache == null) 
                    rei.RemotingCache[CacheObjType.RemotingData] = cache = new RemotingCachedData(rei);
            } 
            else if ((rpi = mi as RuntimePropertyInfo) != null) 
            {
                cache = (RemotingCachedData)rpi.RemotingCache[CacheObjType.RemotingData]; 
                if (cache == null)
                    rpi.RemotingCache[CacheObjType.RemotingData] = cache = new RemotingCachedData(rpi);
            }
            else if ((sfi = mi as SerializationFieldInfo) != null) 
            {
                cache = (RemotingCachedData)sfi.RemotingCache[CacheObjType.RemotingData]; 
                if (cache == null) 
                    sfi.RemotingCache[CacheObjType.RemotingData] = cache = new RemotingCachedData(sfi);
            } 
            else
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));

            return cache; 
        }// GetCachedRemotingAttribute
 
        internal static RemotingCachedData GetReflectionCachedData(RuntimeParameterInfo reflectionObject) 
        {
            RemotingCachedData cache = null; 
            cache = (RemotingCachedData)reflectionObject.RemotingCache[CacheObjType.RemotingData];
            if (cache == null)
            {
                cache = new RemotingCachedData(reflectionObject); 
                reflectionObject.RemotingCache[CacheObjType.RemotingData] = cache;
            } 
 
            return cache;
        } // GetCachedRemotingAttribute 


        [System.Security.SecurityCritical]  // auto-generated
        public static SoapAttribute GetCachedSoapAttribute(Object reflectionObject) 
        {
            MemberInfo mi = reflectionObject as MemberInfo; 
            RuntimeParameterInfo parameter = reflectionObject as RuntimeParameterInfo; 
            if (mi != null)
                return GetReflectionCachedData(mi).GetSoapAttribute(); 
            else if (parameter != null)
                return GetReflectionCachedData(parameter).GetSoapAttribute();
            else
                return null; 
        } // GetCachedSoapAttribute
 
 
    } // InternalRemotingServices
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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