The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting \ RemotingServices

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** File:    RemotingServices.cs
  18. **
  19. ** Author(s):                                       
  20. **
  21. ** Purpose: Defines various remoting related services such as
  22. **          marshal, unmarshal, connect, wrap, unwrap etc.
  23. **
  24. **
  25. ===========================================================*/
  26. namespace System.Runtime.Remoting
  27. {
  28.     using System;
  29.     using System.Text;
  30.     using System.Collections;
  31.     using System.Runtime.Serialization;
  32.     using System.IO;
  33.     using System.Reflection;
  34.     using System.Reflection.Cache;
  35.     using System.Runtime.CompilerServices;
  36.     using CultureInfo = System.Globalization.CultureInfo;
  37.     using System.Runtime.InteropServices;
  38.     using System.Threading;
  39.     using System.Runtime.Remoting.Activation;
  40.     using System.Runtime.Remoting.Contexts;
  41.     using System.Runtime.Remoting.Lifetime;
  42.     using System.Runtime.Remoting.Messaging;
  43.     using System.Runtime.Remoting.Metadata;
  44.     using System.Runtime.Remoting.Proxies;
  45.     using System.Runtime.Remoting.Channels;
  46.     using System.Runtime.Remoting.Services;
  47.     using RemotingConfigInfo = System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo;
  48.     using System.Runtime.Serialization.Formatters.Binary;
  49.     using System.Security.Permissions;
  50.     using System.Runtime.ConstrainedExecution;
  51.    
  52.    
  53.     // Implements various remoting services
  54.     [System.Runtime.InteropServices.ComVisible(true)]
  55.     public sealed class RemotingServices
  56.     {
  57.        
  58.         private const BindingFlags LookupAll = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
  59.         private const string FieldGetterName = "FieldGetter";
  60.         private const string FieldSetterName = "FieldSetter";
  61.         private const string IsInstanceOfTypeName = "IsInstanceOfType";
  62.         private const string CanCastToXmlTypeName = "CanCastToXmlType";
  63.         private const string InvokeMemberName = "InvokeMember";
  64.        
  65.         static internal SecurityPermission s_RemotingInfrastructurePermission;
  66.         static internal Assembly s_MscorlibAssembly;
  67.         private static MethodBase s_FieldGetterMB;
  68.         private static MethodBase s_FieldSetterMB;
  69.         private static MethodBase s_IsInstanceOfTypeMB;
  70.         private static MethodBase s_CanCastToXmlTypeMB;
  71.         private static MethodBase s_InvokeMemberMB;
  72.        
  73.         private static bool s_bRemoteActivationConfigured;
  74.        
  75.         // have we registered the well known channels
  76.         private static bool s_bRegisteredWellKnownChannels;
  77.         // are we in the middle of registering well known channels
  78.         private static bool s_bInProcessOfRegisteringWellKnownChannels;
  79.         private static object s_delayLoadChannelLock;
  80.        
  81.         // Note: This class can be loaded into a new appdomain before the appdomain is fully setup
  82.         // security-wise. Therefore, I've wrapped all the static initialization into an explicit
  83.         // static class initializer and placed an assert that will terminate any stackwalk before
  84.         // it reaches the appdomain transition.
  85.        
  86.         static RemotingServices()
  87.         {
  88.             System.Security.CodeAccessPermission.AssertAllPossible();
  89.             s_RemotingInfrastructurePermission = new SecurityPermission(SecurityPermissionFlag.Infrastructure);
  90.             s_MscorlibAssembly = typeof(RemotingServices).Assembly;
  91.             s_FieldGetterMB = null;
  92.             s_FieldSetterMB = null;
  93.             s_bRemoteActivationConfigured = false;
  94.             s_bRegisteredWellKnownChannels = false;
  95.             s_bInProcessOfRegisteringWellKnownChannels = false;
  96.             s_delayLoadChannelLock = new object();
  97.         }
  98.        
  99.         // Private constructor to prevent users from creating instances of
  100.         // remoting services class.
  101.         //
  102.         //
  103.         private RemotingServices()
  104.         {
  105.         }
  106.        
  107.         //
  108.         //Native Static Methods
  109.         //
  110.        
  111.         [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  112.         public static extern bool IsTransparentProxy(object proxy);
  113.        
  114.        
  115.         // Check whether the given object's context is the same as
  116.         // the current context.
  117.         //
  118.         //
  119.         //
  120.         public static bool IsObjectOutOfContext(object tp)
  121.         {
  122.             if (!IsTransparentProxy(tp)) {
  123.                 return false;
  124.             }
  125.            
  126.             RealProxy rp = GetRealProxy(tp);
  127.             Identity id = rp.IdentityObject;
  128.             ServerIdentity serverID = id as ServerIdentity;
  129.             if ((null == serverID) || !(rp is RemotingProxy)) {
  130.                 return true;
  131.             }
  132.            
  133.             return (Thread.CurrentContext != serverID.ServerContext);
  134.         }
  135.        
  136.        
  137.         // Check whether the given object's app domain is the same as
  138.         // the current app domain
  139.         //
  140.         //
  141.         //
  142.         public static bool IsObjectOutOfAppDomain(object tp)
  143.         {
  144.             return IsClientProxy(tp);
  145.         }
  146.         // IsObjectOutOfAppDomain
  147.        
  148.         static internal bool IsClientProxy(object obj)
  149.         {
  150.             MarshalByRefObject mbr = obj as MarshalByRefObject;
  151.             if (mbr == null)
  152.                 return false;
  153.            
  154.             bool bIsClientProxy = false;
  155.            
  156.             bool fServer;
  157.             Identity id = MarshalByRefObject.GetIdentity(mbr, out fServer);
  158.             // If the identity is null, this is defintely a locally hosted object;
  159.             // otherwise...(see if statement below).
  160.             if (id != null) {
  161.                 if (!(id is ServerIdentity))
  162.                     bIsClientProxy = true;
  163.             }
  164.            
  165.             return bIsClientProxy;
  166.         }
  167.         // IsClientProxy
  168.        
  169.         // Check whether the given object's process is the same as
  170.         // the current process
  171.         //
  172.         //
  173.         //
  174.         static internal bool IsObjectOutOfProcess(object tp)
  175.         {
  176.             if (!IsTransparentProxy(tp))
  177.                 return false;
  178.            
  179.             RealProxy rp = GetRealProxy(tp);
  180.             Identity id = rp.IdentityObject;
  181.             if (id is ServerIdentity)
  182.                 return false;
  183.             else {
  184.                 if (null != id) {
  185.                     ObjRef objRef = id.ObjectRef;
  186.                     if (objRef != null && objRef.IsFromThisProcess()) {
  187.                         return false;
  188.                     }
  189.                     else {
  190.                         return true;
  191.                     }
  192.                 }
  193.                 // assume out of process
  194.                 return true;
  195.             }
  196.            
  197.         }
  198.         // IsObjectOutOfProcess
  199.         // Get the real proxy backing the transparent proxy
  200.         //
  201.         //
  202.         //
  203.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  204.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  205.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  206.         public static extern RealProxy GetRealProxy(object proxy);
  207.        
  208.        
  209.         // Create a transparent proxy given an instance of a real proxy and type
  210.         //
  211.         //
  212.         //
  213.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  214.         static internal extern object CreateTransparentProxy(RealProxy rp, RuntimeType typeToProxy, IntPtr stub, object stubData);
  215.        
  216.         // Note: for each of these calls that take a RuntimeXXX reflection
  217.         // structure, there is a wrapper that takes XXX and throws if it is
  218.         // not a RuntimeXXX. This is to avoid clutter in code where these
  219.         // methods are called.
  220.        
  221.         static internal object CreateTransparentProxy(RealProxy rp, Type typeToProxy, IntPtr stub, object stubData)
  222.         {
  223.             RuntimeType rTypeToProxy = typeToProxy as RuntimeType;
  224.             if (rTypeToProxy == null)
  225.                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_WrongType"), "typeToProxy"));
  226.            
  227.             return CreateTransparentProxy(rp, rTypeToProxy, stub, stubData);
  228.         }
  229.        
  230.        
  231.        
  232.         // Allocate an uninitialized object of the given type.
  233.         //
  234.         //
  235.         //
  236.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  237.         static internal extern MarshalByRefObject AllocateUninitializedObject(RuntimeType objectType);
  238.        
  239.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  240.         static internal extern void CallDefaultCtor(object o);
  241.        
  242.        
  243.         static internal MarshalByRefObject AllocateUninitializedObject(Type objectType)
  244.         {
  245.             RuntimeType rObjectType = objectType as RuntimeType;
  246.             if (rObjectType == null)
  247.                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_WrongType"), "objectType"));
  248.             return AllocateUninitializedObject(rObjectType);
  249.         }
  250.        
  251.         // Allocate an Initialized object of the given type.
  252.         // runs the default constructor
  253.         //
  254.         //
  255.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  256.         static internal extern MarshalByRefObject AllocateInitializedObject(RuntimeType objectType);
  257.        
  258.        
  259.         static internal MarshalByRefObject AllocateInitializedObject(Type objectType)
  260.         {
  261.             RuntimeType rObjectType = objectType as RuntimeType;
  262.             if (rObjectType == null)
  263.                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_WrongType"), "objectType"));
  264.             return AllocateInitializedObject(rObjectType);
  265.         }
  266.        
  267.        
  268.         static internal bool RegisterWellKnownChannels()
  269.         {
  270.             // Any code coming through this method MUST not exit
  271.             // until the well known channels have been registered
  272.             // (unless we are reentering in the call to
  273.             // RefreshChannelData() while registering a well known
  274.             // channel).
  275.             if (!s_bRegisteredWellKnownChannels) {
  276.                 bool fLocked = false;
  277.                 object configLock = Thread.GetDomain().RemotingData.ConfigLock;
  278.                 RuntimeHelpers.PrepareConstrainedRegions();
  279.                 try {
  280.                     Monitor.ReliableEnter(configLock, ref fLocked);
  281.                     if (!s_bRegisteredWellKnownChannels && !s_bInProcessOfRegisteringWellKnownChannels) {
  282.                        
  283.                         // we set this flag true before registering channels to prevent reentrancy
  284.                         // when we go to refresh the channel data at the end of the call to
  285.                         // ChannelServices.RegisterChannel().
  286.                         s_bInProcessOfRegisteringWellKnownChannels = true;
  287.                         CrossAppDomainChannel.RegisterChannel();
  288.                         s_bRegisteredWellKnownChannels = true;
  289.                     }
  290.                 }
  291.                 finally {
  292.                     if (fLocked) {
  293.                         Monitor.Exit(configLock);
  294.                     }
  295.                 }
  296.             }
  297.             return true;
  298.         }
  299.         // RegisterWellKnownChannels
  300.        
  301.         static internal void InternalSetRemoteActivationConfigured()
  302.         {
  303.             if (!s_bRemoteActivationConfigured) {
  304.                 nSetRemoteActivationConfigured();
  305.                 s_bRemoteActivationConfigured = true;
  306.             }
  307.         }
  308.         // InternalSetRemoteActivationConfigured
  309.        
  310.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  311.         private static extern void nSetRemoteActivationConfigured();
  312.        
  313.        
  314.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  315.         public static string GetSessionIdForMethodMessage(IMethodMessage msg)
  316.         {
  317.             return msg.Uri;
  318.         }
  319.         // GetSessionIdForMessage
  320.         public static object GetLifetimeService(MarshalByRefObject obj)
  321.         {
  322.             if (null != obj) {
  323.                 return obj.GetLifetimeService();
  324.             }
  325.             else {
  326.                 return null;
  327.             }
  328.         }
  329.        
  330.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  331.         public static string GetObjectUri(MarshalByRefObject obj)
  332.         {
  333.             // Retrieve the uri for the object. If it doesn't have an identity
  334.             // we'll just return null (this encompasses the case of an actual
  335.             // object not having been marshalled yet.
  336.            
  337.             bool fServer;
  338.             Identity id = MarshalByRefObject.GetIdentity(obj, out fServer);
  339.            
  340.             if (null != id)
  341.                 return id.URI;
  342.             else
  343.                 return null;
  344.         }
  345.         // GetObjectUri
  346.        
  347.         [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  348.         public static void SetObjectUriForMarshal(MarshalByRefObject obj, string uri)
  349.         {
  350.             // if obj is ever Marshal'd it should use this uri. If a uri has
  351.             // already been assigned to the object, it should throw.
  352.            
  353.             Message.DebugOut("Entered SetObjectUriForMarshal \n");
  354.            
  355.             Identity idObj = null;
  356.             Identity srvIdObj = null;
  357.            
  358.             bool fServer;
  359.             idObj = MarshalByRefObject.GetIdentity(obj, out fServer);
  360.             srvIdObj = idObj as ServerIdentity;
  361.            
  362.             // Ensure that if we have a transparent proxy then we are not given a remoting
  363.             // proxy. This routine should only be called for objects that
  364.             // live in this AppDomains.
  365.             // <-- means idObj is not a ServerIdentity
  366.             if ((idObj != null) && (srvIdObj == null)) {
  367.                 throw new RemotingException(Environment.GetResourceString("Remoting_SetObjectUriForMarshal__ObjectNeedsToBeLocal"));
  368.             }
  369.            
  370.            
  371.             if ((idObj != null) && (idObj.URI != null)) {
  372.                 throw new RemotingException(Environment.GetResourceString("Remoting_SetObjectUriForMarshal__UriExists"));
  373.             }
  374.            
  375.            
  376.             if (idObj == null) {
  377.                 // obj is not ContextBound
  378.                 BCLDebug.Assert(!(obj is ContextBoundObject), "ContextBoundObject's shouldn't get here.");
  379.                
  380.                 // Create a new server identity and add it to the
  381.                 // table. IdentityHolder will take care of races
  382.                 Context serverCtx = null;
  383.                
  384.                 serverCtx = Thread.GetDomain().GetDefaultContext();
  385.                
  386.                 BCLDebug.Assert(null != serverCtx, "null != serverCtx");
  387.                
  388.                 ServerIdentity serverID = new ServerIdentity(obj, serverCtx, uri);
  389.                
  390.                 // set the identity
  391.                 idObj = obj.__RaceSetServerIdentity(serverID);
  392.                 BCLDebug.Assert(idObj == MarshalByRefObject.GetIdentity(obj), "Bad ID state!");
  393.                
  394.                 // If our serverID isn't used then someone else marshalled the object
  395.                 // before we could set the uri.
  396.                 if (idObj != serverID) {
  397.                     throw new RemotingException(Environment.GetResourceString("Remoting_SetObjectUriForMarshal__UriExists"));
  398.                 }
  399.             }
  400.             else {
  401.                 // This is the ContextBoundObject case
  402.                 BCLDebug.Assert(obj is ContextBoundObject, "Object should have been a ContextBoundObject.");
  403.                
  404.                 idObj.SetOrCreateURI(uri, true);
  405.             }
  406.            
  407.             Message.DebugOut("Created ServerIdentity \n");
  408.         }
  409.         // SetObjectUriForMarshal
  410.        
  411.         [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  412.         public static ObjRef Marshal(MarshalByRefObject Obj)
  413.         {
  414.             return MarshalInternal(Obj, null, null);
  415.         }
  416.        
  417.         [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  418.         public static ObjRef Marshal(MarshalByRefObject Obj, string URI)
  419.         {
  420.             return MarshalInternal(Obj, URI, null);
  421.         }
  422.        
  423.         [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  424.         public static ObjRef Marshal(MarshalByRefObject Obj, string ObjURI, Type RequestedType)
  425.         {
  426.             return MarshalInternal(Obj, ObjURI, RequestedType);
  427.         }
  428.        
  429.         // Internal flavor without security!
  430.         static internal ObjRef MarshalInternal(MarshalByRefObject Obj, string ObjURI, Type RequestedType)
  431.         {
  432.             return MarshalInternal(Obj, ObjURI, RequestedType, true);
  433.         }
  434.         // Internal flavor without security!
  435.         static internal ObjRef MarshalInternal(MarshalByRefObject Obj, string ObjURI, Type RequestedType, bool updateChannelData)
  436.         {
  437.             BCLDebug.Trace("REMOTE", "Entered Marshal for URI" + ObjURI + "\n");
  438.            
  439.             if (null == Obj)
  440.                 return null;
  441.            
  442.             ObjRef objectRef = null;
  443.             Identity idObj = null;
  444.            
  445.             idObj = GetOrCreateIdentity(Obj, ObjURI);
  446.             if (RequestedType != null) {
  447.                 ServerIdentity srvIdObj = idObj as ServerIdentity;
  448.                 if (srvIdObj != null) {
  449.                     // If more than one thread, marshals with different types the
  450.                     // results would be non-deterministic, so we just let the last
  451.                     // call win (also allows type to be marshalled a second time
  452.                     // to change the exposed type).
  453.                     srvIdObj.ServerType = RequestedType;
  454.                     srvIdObj.MarshaledAsSpecificType = true;
  455.                 }
  456.             }
  457.            
  458.             // If there is no objref associated with the identity then go ahead
  459.             // and create one and stick it back into the identity object
  460.            
  461.             #if _DEBUG
  462.             idObj.AssertValid();
  463.             #endif
  464.            
  465.             BCLDebug.Assert(null != idObj.ObjURI, "null != idObj.ObjURI");
  466.            
  467.             Message.DebugOut("RemotingServices::Marshal: trying to create objref\n");
  468.            
  469.             // We should definitely have an identity object at this point of time
  470.             BCLDebug.Assert(null != idObj, "null != idObj");
  471.            
  472.             // Extract the objref from the identity
  473.             objectRef = idObj.ObjectRef;
  474.             if (null == objectRef) {
  475.                 Message.DebugOut("RemotingServices::Marshal: really trying to create objref\n");
  476.                
  477.                 if (IsTransparentProxy(Obj)) {
  478.                     RealProxy realProxy = GetRealProxy(Obj);
  479.                     BCLDebug.Assert(null != realProxy, "null != realProxy");
  480.                     objectRef = realProxy.CreateObjRef(RequestedType);
  481.                 }
  482.                 else {
  483.                     // Create a new object ref which contains the default information
  484.                     objectRef = Obj.CreateObjRef(RequestedType);
  485.                 }
  486.                
  487.                 Message.DebugOut("RemotingServices::Marshal: created objref\n");
  488.                 BCLDebug.Assert(null != idObj, "null != idObj");
  489.                 BCLDebug.Assert(null != objectRef, "null != objectRef");
  490.                 // The ObjectRef property setter will take care of races
  491.                 objectRef = idObj.RaceSetObjRef(objectRef);
  492.             }
  493.            
  494.            
  495.             // Retime lease on every marshal on the server side
  496.             // and extend lease on every marshal on the client side
  497.             ServerIdentity srvId = idObj as ServerIdentity;
  498.             if (srvId != null) {
  499.                 // Ensure that the lease is started soon as the object is
  500.                 // marshaled.
  501.                 MarshalByRefObject obj = null;
  502.                 // This call forces creation of the lifetime lease sink.
  503.                 srvId.GetServerObjectChain(out obj);
  504.                
  505.                 // Server side ... object being marshaled => give it another
  506.                 // full lease
  507.                 Lease lease = idObj.Lease;
  508.                 if (lease != null) {
  509.                     // We always make Identity reference our own Lease though
  510.                     // the actual object implements its own ILease object.
  511.                     // This seems completely broken. Further, ILease interface
  512.                     // should have the activate method.
  513.                    
  514.                     // This lock ensures coordination with the lifetime service
  515.                     // which might have decided to Disconnect the object about
  516.                     // the same time as it is being marshaled
  517.                     lock (lease) {
  518.                         if (lease.CurrentState == LeaseState.Expired) {
  519.                             // Lease.Renew is a no-op if LeaseState==Expired
  520.                             // So we do a full ActivateLease
  521.                             lease.ActivateLease();
  522.                         }
  523.                         else {
  524.                             // Lease is still around. Just increase the time
  525.                             lease.RenewInternal(idObj.Lease.InitialLeaseTime);
  526.                         }
  527.                     }
  528.                 }
  529.                
  530.                 // Every marshal should also ensure that the channel data
  531.                 // being carried in the objRef reflects the latest data from
  532.                 // regisetered channels
  533.                 if (updateChannelData && objectRef.ChannelInfo != null) {
  534.                     // Create the channel info
  535.                     object[] channelData = ChannelServices.CurrentChannelData;
  536.                     // Make sure the channelInfo only has x-appdomain data since the objref is agile while other
  537.                     // channelData might not be and regardless this data is useless for an appdomain proxy
  538.                     if (!(Obj is AppDomain))
  539.                         objectRef.ChannelInfo.ChannelData = channelData;
  540.                     else {
  541.                         int channelDataLength = channelData.Length;
  542.                         object[] newChannelData = new object[channelDataLength];
  543.                         Array.Copy(channelData, newChannelData, channelDataLength);
  544.                         for (int i = 0; i < channelDataLength; i++) {
  545.                             if (!(newChannelData[i] is CrossAppDomainData))
  546.                                 newChannelData[i] = null;
  547.                         }
  548.                         objectRef.ChannelInfo.ChannelData = newChannelData;
  549.                     }
  550.                 }
  551.             }
  552.             else {
  553.             }
  554.            
  555.             // Notify TrackingServices that an object has been marshaled
  556.             // NOTE: This call also keeps the object alive otherwise GC
  557.             // can report it as dead anytime inside this call when it thinks
  558.             // that the object will no longer be referenced, either inside
  559.             // this call or outside.
  560.             /*                                                                     
  561.                                                                       */           
  562.            
  563. TrackingServices.MarshaledObject(Obj, objectRef);
  564.             return objectRef;
  565.         }
  566.        
  567.         // Gets or generates the identity if one is not present and then returns
  568.         // it to the caller.
  569.         private static Identity GetOrCreateIdentity(MarshalByRefObject Obj, string ObjURI)
  570.         {
  571.             Identity idObj = null;
  572.             if (IsTransparentProxy(Obj)) {
  573.                 Message.DebugOut("Marshaling proxy \n");
  574.                
  575.                 RealProxy realProxy = GetRealProxy(Obj);
  576.                 BCLDebug.Assert(null != realProxy, "null != realProxy");
  577.                
  578.                 idObj = realProxy.IdentityObject;
  579.                 if (null == idObj) {
  580.                     // passing the strongIdentity flag will ensure that a weak
  581.                     // reference to the identity will get converted to a strong
  582.                     // one so as to keep the object alive (and in control of
  583.                     // lifeTimeServices)
  584.                    
  585.                     idObj = IdentityHolder.FindOrCreateServerIdentity(Obj, ObjURI, IdOps.StrongIdentity);
  586.                    
  587.                     idObj.RaceSetTransparentProxy(Obj);
  588.                 }
  589.                
  590.                 // At this point of time we should have an identity
  591.                 BCLDebug.Assert(null != idObj, "null != idObj");
  592.                
  593.                
  594.                 ServerIdentity srvID = idObj as ServerIdentity;
  595.                 if (srvID != null) {
  596.                     // We are marshaling a proxy with a serverIdentity
  597.                     // associated with it but with no URI generated yet.
  598.                     // For a genuine proxy case we will always have a URI
  599.                     // AND it will be a client ID!
  600.                     // So if we are here this must be a SrvID
  601.                     // for a ContextBoundObject
  602.                     BCLDebug.Assert(srvID != null && Obj is ContextBoundObject, "This case should only be hit for ContextBoundObjects & ServerIdentity!");
  603.                     Message.DebugOut("Marshal::Looking up server side identity \n");
  604.                     #if _DEBUG
  605.                     srvID.AssertValid();
  606.                     #endif
  607.                    
  608.                     // passing the strongIdentity flag will ensure that a weak
  609.                     // reference to the identity will get converted to a strong
  610.                     // one so as to keep the object alive (and in control of
  611.                     // lifeTimeServices)
  612.                    
  613.                     idObj = IdentityHolder.FindOrCreateServerIdentity(srvID.TPOrObject, ObjURI, IdOps.StrongIdentity);
  614.                    
  615.                     // if an objURI was specified we need to make sure that
  616.                     // the same one was used.
  617.                     if ((null != ObjURI) && (ObjURI != Identity.RemoveAppNameOrAppGuidIfNecessary(idObj.ObjURI))) {
  618.                         throw new RemotingException(Environment.GetResourceString("Remoting_URIExists"));
  619.                     }
  620.                    
  621.                     // We create a unique ID for an object and never
  622.                     // change it!
  623.                     BCLDebug.Assert(srvID == idObj, "Bad ID Table state!");
  624.                 }
  625.                 else {
  626.                     // We are marshaling a proxy with a (client)Identity associated with it
  627.                     // It must already have a URI.
  628.                     Message.DebugOut("Marshal::Client side identity \n");
  629.                     BCLDebug.Assert(idObj.ObjURI != null, "Client side id without URI!");
  630.                    
  631.                     //
  632.                     // One cannot associate a URI with a proxy generated by us
  633.                     // because either a URI was generated at the server side for the object
  634.                     // it represents or it is a well known object in which case the URI is known.
  635.                     //
  636.                     // For custom proxies this restriction is relaxed because we treat the
  637.                     // transparent proxy as the server object for such cases.
  638.                     //
  639.                     if ((null != ObjURI) && (ObjURI != idObj.ObjURI)) {
  640.                         throw new RemotingException(Environment.GetResourceString("Remoting_URIToProxy"));
  641.                     }
  642.                 }
  643.                
  644.                 BCLDebug.Assert(null != idObj.ObjURI, "null != idObj.ObjURI");
  645.             }
  646.             else {
  647.                 // Find or Add the object identity to the identity table
  648.                 Message.DebugOut("Marshaling object \n");
  649.                
  650.                 // passing the strongIdentity flag will ensure that a weak
  651.                 // reference to the identity will get converted to a strong
  652.                 // one so as to keep the object alive (and in control of
  653.                 // lifeTimeServices)
  654.                
  655.                 // The object may have an ID if it was marshaled but its lease
  656.                 // timed out.
  657.                 #if _DEBUG
  658.                 ServerIdentity idTmp = (ServerIdentity)MarshalByRefObject.GetIdentity(Obj);
  659.                 #endif
  660.                
  661.                
  662.                
  663.                 idObj = IdentityHolder.FindOrCreateServerIdentity(Obj, ObjURI, IdOps.StrongIdentity);
  664.                
  665.                 // If the object had an ID to begin with that is the one
  666.                 // we must have set in the table.
  667.                 #if _DEBUG
  668.                 BCLDebug.Assert(idTmp == null || idTmp == idObj, "Bad ID Table state!");
  669.                 #endif
  670.             }
  671.            
  672.             return idObj;
  673.         }
  674.        
  675.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  676.         public static void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
  677.         {
  678.             if (obj == null) {
  679.                 throw new ArgumentNullException("obj");
  680.             }
  681.            
  682.             if (info == null) {
  683.                 throw new ArgumentNullException("info");
  684.             }
  685.            
  686.             ObjRef or = RemotingServices.MarshalInternal((MarshalByRefObject)obj, null, null);
  687.            
  688.             or.GetObjectData(info, context);
  689.         }
  690.         // GetObjectData
  691.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  692.         public static object Unmarshal(ObjRef objectRef)
  693.         {
  694.             return InternalUnmarshal(objectRef, null, false);
  695.         }
  696.        
  697.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  698.         public static object Unmarshal(ObjRef objectRef, bool fRefine)
  699.         {
  700.             return InternalUnmarshal(objectRef, null, fRefine);
  701.         }
  702.        
  703.        
  704.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  705.         [System.Runtime.InteropServices.ComVisible(true)]
  706.         public static object Connect(Type classToProxy, string url)
  707.         {
  708.             return Unmarshal(classToProxy, url, null);
  709.         }
  710.        
  711.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  712.         [System.Runtime.InteropServices.ComVisible(true)]
  713.         public static object Connect(Type classToProxy, string url, object data)
  714.         {
  715.             return Unmarshal(classToProxy, url, data);
  716.         }
  717.        
  718.        
  719.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  720.         public static bool Disconnect(MarshalByRefObject obj)
  721.         {
  722.             return Disconnect(obj, true);
  723.         }
  724.        
  725.         static internal bool Disconnect(MarshalByRefObject obj, bool bResetURI)
  726.         {
  727.             BCLDebug.Trace("REMOTE", "RemotingServices.Disconnect ", obj, " for context ", Thread.CurrentContext);
  728.             if (obj == null) {
  729.                 throw new ArgumentNullException("obj");
  730.             }
  731.            
  732.             // We can extract the identity either from the remoting proxy or
  733.             // the server object depending on whether we are in the
  734.             // context/appdomain that the object was created in or outside
  735.             // the context/appdomain.
  736.             bool fServer;
  737.             Identity idrem = MarshalByRefObject.GetIdentity(obj, out fServer);
  738.            
  739.             // remove the identity entry for this object (if it exists)
  740.             bool fDisconnect = false;
  741.             if (idrem != null) {
  742.                 // Disconnect is supported only on the server side currently
  743.                 if (idrem is ServerIdentity) {
  744.                     // Disconnect is a no op if the object was never marshaled
  745.                     if (idrem.IsInIDTable()) {
  746.                         // When a user calls Disconnect we reset the URI but
  747.                         // when lifetime service calls Disconnect we don't
  748.                         IdentityHolder.RemoveIdentity(idrem.URI, bResetURI);
  749.                         fDisconnect = true;
  750.                     }
  751.                 }
  752.                 else {
  753.                     throw new RemotingException(Environment.GetResourceString("Remoting_CantDisconnectClientProxy"));
  754.                 }
  755.                
  756.                 // Notify TrackingServices that an object has been disconnected
  757.                 TrackingServices.DisconnectedObject(obj);
  758.             }
  759.            
  760.             Message.DebugOut("Disconnect:: returning " + fDisconnect + " for context " + Thread.CurrentContext + "\n");
  761.            
  762.             return fDisconnect;
  763.         }
  764.        
  765.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  766.         public static IMessageSink GetEnvoyChainForProxy(MarshalByRefObject obj)
  767.         {
  768.             IMessageSink envoyChain = null;
  769.            
  770.             // Extract the envoy chain only if the object is a proxy
  771.             if (IsObjectOutOfContext(obj)) {
  772.                 RealProxy rp = GetRealProxy(obj);
  773.                 Identity id = rp.IdentityObject;
  774.                 if (null != id) {
  775.                     envoyChain = id.EnvoyChain;
  776.                 }
  777.             }
  778.            
  779.             return envoyChain;
  780.         }
  781.        
  782.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  783.         public static ObjRef GetObjRefForProxy(MarshalByRefObject obj)
  784.         {
  785.             ObjRef objRef = null;
  786.             if (!IsTransparentProxy(obj)) {
  787.                 throw new RemotingException(Environment.GetResourceString("Remoting_Proxy_BadType"));
  788.             }
  789.             RealProxy rp = GetRealProxy(obj);
  790.             Identity id = rp.IdentityObject;
  791.             if (null != id) {
  792.                 objRef = id.ObjectRef;
  793.             }
  794.             return objRef;
  795.         }
  796.        
  797.         static internal object Unmarshal(Type classToProxy, string url)
  798.         {
  799.             return Unmarshal(classToProxy, url, null);
  800.         }
  801.        
  802.        
  803.         static internal object Unmarshal(Type classToProxy, string url, object data)
  804.         {
  805.             if (null == classToProxy) {
  806.                 throw new ArgumentNullException("classToProxy");
  807.             }
  808.            
  809.             if (null == url) {
  810.                 throw new ArgumentNullException("url");
  811.             }
  812.            
  813.             if (!classToProxy.IsMarshalByRef && !classToProxy.IsInterface) {
  814.                 throw new RemotingException(Environment.GetResourceString("Remoting_NotRemotableByReference"));
  815.             }
  816.            
  817.             BCLDebug.Trace("REMOTE", "RemotingService::Unmarshal for URL" + url + "and for Type" + classToProxy);
  818.            
  819.             // See if we have already unmarshaled this (wellKnown) url
  820.             Identity idObj = IdentityHolder.ResolveIdentity(url);
  821.             object proxy = null;
  822.             if (idObj == null || idObj.ChannelSink == null || idObj.EnvoyChain == null) {
  823.                 string objectURI = null;
  824.                 IMessageSink chnlSink = null;
  825.                 IMessageSink envoySink = null;
  826.                 // Create the envoy and channel sinks
  827.                 objectURI = CreateEnvoyAndChannelSinks(url, data, out chnlSink, out envoySink);
  828.                
  829.                 // ensure that we were able to create a channel sink
  830.                 if (chnlSink == null) {
  831.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Connect_CantCreateChannelSink"), url));
  832.                 }
  833.                
  834.                 // Do not allow Connect() with null objUri (eg. http://localhost/)
  835.                 if (objectURI == null) {
  836.                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl"));
  837.                    
  838.                 }
  839.                
  840.                
  841.                 // Try to find an existing identity or create a new one
  842.                 // Note: we create an identity entry hashed with the full url. This
  843.                 // means that the same well known object could have multiple
  844.                 // identities on the client side if it is connected through urls
  845.                 // that have different string representations.
  846.                
  847.                 // Also, we are resetting the envoy and channel sinks on an existing identity
  848.                 // as FindOrCreateIdentity can return an existing identity established by an
  849.                 // earlier call
  850.                 idObj = IdentityHolder.FindOrCreateIdentity(objectURI, url, null);
  851.                
  852.                 // Set the envoy and channel sinks in a thread safe manner
  853.                 SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
  854.             }
  855.            
  856.             // Get the proxy represented by the identity object
  857.             proxy = GetOrCreateProxy(classToProxy, idObj);
  858.            
  859.             Message.DebugOut("RemotingService::Unmarshal returning ");
  860.            
  861.             return proxy;
  862.         }
  863.        
  864.         static internal object Wrap(ContextBoundObject obj)
  865.         {
  866.             return Wrap(obj, null, true);
  867.         }
  868.        
  869.         static internal object Wrap(ContextBoundObject obj, object proxy, bool fCreateSinks)
  870.         {
  871.             Message.DebugOut("Entering Wrap for context " + Thread.CurrentContext + "\n");
  872.            
  873.             if ((null != obj) && (!IsTransparentProxy(obj))) {
  874.                 BCLDebug.Assert(obj.GetType().IsContextful, "objType.IsContextful");
  875.                 Message.DebugOut("Wrapping object \n");
  876.                 Identity idObj = null;
  877.                
  878.                 if (proxy != null) {
  879.                     // We will come here for strictly x-context activations
  880.                     // since a proxy has already been created and supplied
  881.                     // through the construction message frame (GetThisPtr()).
  882.                     RealProxy rp = GetRealProxy(proxy);
  883.                     if (rp.UnwrappedServerObject == null) {
  884.                         rp.AttachServerHelper(obj);
  885.                     }
  886.                     idObj = MarshalByRefObject.GetIdentity(obj);
  887.                 }
  888.                 else {
  889.                     // Proxy is null when Wrap() is called the second
  890.                     // time during activation
  891.                     // It also will be null when a ContextBoundObject
  892.                     // is being activated from a remote client.
  893.                     idObj = IdentityHolder.FindOrCreateServerIdentity(obj, null, IdOps.None);
  894.                 }
  895.                
  896.                 //********************WARNING*******************************
  897.                 // Always create the proxy before calling out to user code
  898.                 // so that any recursive calls by JIT to wrap will return this
  899.                 // proxy.
  900.                 //**********************************************************
  901.                 // Get the proxy represented by the identity object
  902.                 proxy = GetOrCreateProxy(idObj, proxy, true);
  903.                
  904.                 // EXTENSIBILITY:
  905.                 GetRealProxy(proxy).Wrap();
  906.                
  907.                 if (fCreateSinks) {
  908.                     IMessageSink chnlSink = null;
  909.                     IMessageSink envoySink = null;
  910.                     // Create the envoy sinks and channel sink
  911.                     CreateEnvoyAndChannelSinks(obj, null, out chnlSink, out envoySink);
  912.                    
  913.                     // Set the envoy and channel sinks in a thread safe manner
  914.                     SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
  915.                 }
  916.                
  917.                 // This will handle the case where we call Wrap() with
  918.                 // a null proxy for real remote activation of ContextFul types.
  919.                 RealProxy rp2 = GetRealProxy(proxy);
  920.                 if (rp2.UnwrappedServerObject == null) {
  921.                     rp2.AttachServerHelper(obj);
  922.                 }
  923.                 Message.DebugOut("Leaving Wrap with proxy \n");
  924.                 return proxy;
  925.             }
  926.             else {
  927.                 Message.DebugOut("Leaving Wrap with passed in object\n");
  928.                
  929.                 // Default return value is the object itself
  930.                 return obj;
  931.             }
  932.         }
  933.         // Wrap
  934.        
  935.         // This relies on the fact that no object uri is allowed to contain a slash
  936.         // (in some cases, we might want to do something intelligent by parsing
  937.         // the uri with the right channel, but that isn't possible in all cases).
  938.         static internal string GetObjectUriFromFullUri(string fullUri)
  939.         {
  940.             if (fullUri == null)
  941.                 return null;
  942.            
  943.             int index = fullUri.LastIndexOf('/');
  944.             if (index == -1)
  945.                 return fullUri;
  946.            
  947.             return fullUri.Substring(index + 1);
  948.         }
  949.         // GetObjectUriFromFullUri
  950.        
  951.         //
  952.         //
  953.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  954.         static internal extern object Unwrap(ContextBoundObject obj);
  955.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  956.         static internal extern object AlwaysUnwrap(ContextBoundObject obj);
  957.        
  958.        
  959.         // This method does the actual work of Ma
  960.         //
  961.        
  962.         static internal object InternalUnmarshal(ObjRef objectRef, object proxy, bool fRefine)
  963.         {
  964.             object obj = null;
  965.             Identity idObj = null;
  966.            
  967.             Context currContext = Thread.CurrentContext;
  968.             Message.DebugOut("RemotingServices::InternalUnmarshal: <Begin> Current context id: " + (currContext.ContextID).ToString("x") + "\n");
  969.            
  970.             // This routine can be supplied a custom objref or an objref
  971.             // generated by us. We do some sanity checking on the objref
  972.             // to make sure that it is valid
  973.             if (!ObjRef.IsWellFormed(objectRef)) {
  974.                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_BadObjRef"), "Unmarshal"));
  975.             }
  976.            
  977.             // If it is a well known objectRef we need to just connect to
  978.             // the URL inside the objectRef.
  979.             if (objectRef.IsWellKnown()) {
  980.                 obj = Unmarshal(typeof(System.MarshalByRefObject), objectRef.URI);
  981.                 // ensure that we cache the objectRef in the ID
  982.                 // this contains type-info and we need it for
  983.                 // validating casts on the wellknown proxy
  984.                 // Note: this code path will be relatively rare ... the case
  985.                 // when a well known proxy is passed to a remote call
  986.                 // Otherwise it will be wise to another internal flavor of
  987.                 // Unmarshal call that returns the identity as an out param.
  988.                 idObj = IdentityHolder.ResolveIdentity(objectRef.URI);
  989.                 if (idObj.ObjectRef == null) {
  990.                     idObj.RaceSetObjRef(objectRef);
  991.                 }
  992.                 return obj;
  993.             }
  994.            
  995.             Message.DebugOut("RemotingService::InternalUnmarshal IN URI" + objectRef.URI);
  996.             // Get the identity for the URI
  997.             idObj = IdentityHolder.FindOrCreateIdentity(objectRef.URI, null, objectRef);
  998.            
  999.             currContext = Thread.CurrentContext;
  1000.             Message.DebugOut("RemotingServices::Unmarshal: <after FindOrCreateIdentity> Current context id: " + (currContext.ContextID).ToString("x") + "\n");
  1001.            
  1002.             // If we successfully completed the above method then we should
  1003.             // have an identity object
  1004.             BCLDebug.Assert(null != idObj, "null != idObj");
  1005.            
  1006.            
  1007.             Message.DebugOut("RemotingService::InternalUnmarshal IN URI" + objectRef.URI);
  1008.            
  1009.             Message.DebugOut("RemotingServices::InternalUnmarshal: <Begin> Current context id: " + (currContext.ContextID).ToString("x") + "\n");
  1010.            
  1011.            
  1012.             // Check whether we are on the server side or client-side
  1013.             ServerIdentity serverID = idObj as ServerIdentity;
  1014.             if (serverID != null) {
  1015.                 Message.DebugOut("RemotingServices::InternalUnmarshal: Unmarshalling ServerIdentity\n");
  1016.                
  1017.                 // SERVER SIDE
  1018.                 // We are in the app domain of the server object.
  1019.                 // If we are in the same context as the server then
  1020.                 // just return the server object else return the proxy
  1021.                
  1022.                 currContext = Thread.CurrentContext;
  1023.                 Message.DebugOut("RemotingServices::InternalUnmarshal: Current context id: " + (currContext.ContextID).ToString("x") + "\n");
  1024.                 Message.DebugOut("RemotingServices::InternalUnmarshal: ServerContext id: " + (serverID.ServerContext.ContextID).ToString("x") + "\n");
  1025.                
  1026.                 if (!serverID.IsContextBound) {
  1027.                     BCLDebug.Assert(serverID.ServerType.IsMarshalByRef, "Object must be at least MarshalByRef in order to be marshaled");
  1028.                     if (proxy != null) {
  1029.                         throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadInternalState_ProxySameAppDomain")));
  1030.                     }
  1031.                     obj = serverID.TPOrObject;
  1032.                 }
  1033.                 else {
  1034.                     Message.DebugOut("RemotingServices::InternalUnmarshal: Contexts don't match, returning proxy\n");
  1035.                    
  1036.                     IMessageSink chnlSink = null;
  1037.                     IMessageSink envoySink = null;
  1038.                    
  1039.                     // Create the envoy sinks and channel sink
  1040.                     CreateEnvoyAndChannelSinks((MarshalByRefObject)serverID.TPOrObject, null, out chnlSink, out envoySink);
  1041.                    
  1042.                     // Set the envoy and channel sinks in a thread safe manner
  1043.                     SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
  1044.                    
  1045.                     // Get or create the proxy and return
  1046.                     obj = GetOrCreateProxy(idObj, proxy, true);
  1047.                     // This will be a TP
  1048.                     BCLDebug.Assert(IsTransparentProxy(obj), "Unexpected naked server");
  1049.                 }
  1050.             }
  1051.             else {
  1052.                 // CLIENT SIDE
  1053.                
  1054.                 Message.DebugOut("RemotingServices::InternalUnmarshal: Unmarshalling Client-side Identity\n");
  1055.                
  1056.                 IMessageSink chnlSink = null;
  1057.                 IMessageSink envoySink = null;
  1058.                
  1059.                 // Create the envoy sinks and channel sink
  1060.                 if (!objectRef.IsObjRefLite())
  1061.                     CreateEnvoyAndChannelSinks(null, objectRef, out chnlSink, out envoySink);
  1062.                 else
  1063.                     CreateEnvoyAndChannelSinks(objectRef.URI, null, out chnlSink, out envoySink);
  1064.                
  1065.                 // Set the envoy and channel sinks in a thread safe manner
  1066.                 SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);
  1067.                
  1068.                 if (objectRef.HasProxyAttribute()) {
  1069.                     fRefine = true;
  1070.                 }
  1071.                
  1072.                 // Get or create the proxy and return
  1073.                 obj = GetOrCreateProxy(idObj, proxy, fRefine);
  1074.             }
  1075.            
  1076.             // Notify TrackingServices that we unmarshaled an object
  1077.             TrackingServices.UnmarshaledObject(obj, objectRef);
  1078.            
  1079.             // Return the proxy
  1080.             Message.DebugOut("RemotingService::InternalUnmarshl OUT \n");
  1081.             return obj;
  1082.            
  1083.         }
  1084.        
  1085.         //
  1086.         //
  1087.         private static object GetOrCreateProxy(Identity idObj, object proxy, bool fRefine)
  1088.         {
  1089.             Message.DebugOut("Entering GetOrCreateProxy for given proxy\n");
  1090.            
  1091.             // If we are not supplied a proxy then we have to find an existing
  1092.             // proxy or create one
  1093.             if (null == proxy) {
  1094.                 // Get the type of the server object
  1095.                 Type serverType;
  1096.                 ServerIdentity serverID = idObj as ServerIdentity;
  1097.                 if (null != serverID) {
  1098.                     serverType = serverID.ServerType;
  1099.                     // ServerObject.GetType();
  1100.                 }
  1101.                 else {
  1102.                     BCLDebug.Assert(ObjRef.IsWellFormed(idObj.ObjectRef), "ObjRef.IsWellFormed(idObj.ObjectRef)");
  1103.                     IRemotingTypeInfo serverTypeInfo = idObj.ObjectRef.TypeInfo;
  1104.                    
  1105.                     // For system generated type info we create the proxy for
  1106.                     // object type. Later, when the proxy is cast to the appropriate
  1107.                     // type we will update its internal state to refer to the cast type
  1108.                     // This way we avoid loading the server type till cast time.
  1109.                     //
  1110.                     // For type info generated by others we have no choice but to
  1111.                     // load the type provided by the typeinfo. Sometimes, we
  1112.                     // use this second approach even if the typeinfo has been
  1113.                     // generated by us because this saves us an extra checkcast.
  1114.                     // A typical example of this usage will be when we are
  1115.                     // unmarshaling in parameters. We know that the unmarshal will
  1116.                     // be followed by a check cast to ensure that the parameter type
  1117.                     // matches the signature type, so we do both in one step.
  1118.                     serverType = null;
  1119.                     if (((serverTypeInfo is TypeInfo) && !fRefine) || (serverTypeInfo == null)) {
  1120.                         serverType = typeof(System.MarshalByRefObject);
  1121.                     }
  1122.                     else {
  1123.                         string typeName = serverTypeInfo.TypeName;
  1124.                         if (typeName != null) {
  1125.                             string typeNamespace = null;
  1126.                             string assemNamespace = null;
  1127.                             TypeInfo.ParseTypeAndAssembly(typeName, out typeNamespace, out assemNamespace);
  1128.                            
  1129.                            
  1130.                             Assembly assem = FormatterServices.LoadAssemblyFromStringNoThrow(assemNamespace);
  1131.                            
  1132.                             if (assem != null) {
  1133.                                 serverType = assem.GetType(typeNamespace, false, false);
  1134.                             }
  1135.                            
  1136.                         }
  1137.                        
  1138.                     }
  1139.                    
  1140.                     if (null == serverType) {
  1141.                         throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), serverTypeInfo.TypeName));
  1142.                     }
  1143.                 }
  1144.                 Message.DebugOut("Creating Proxy for type " + serverType.FullName + "\n");
  1145.                 proxy = SetOrCreateProxy(idObj, serverType, null);
  1146.             }
  1147.             else {
  1148.                 // We have been supplied with a proxy. Set that proxy in
  1149.                 // the identity object
  1150.                 // Assert that this the activation case only as this code path is
  1151.                 // not thread safe otherwise! (We call Wrap to associate an object
  1152.                 // with its proxy during activation).
  1153.                 BCLDebug.Assert(((RemotingProxy)GetRealProxy(proxy)).ConstructorMessage != null, "Only expect to be here during activation!");
  1154.                 proxy = SetOrCreateProxy(idObj, null, proxy);
  1155.             }
  1156.            
  1157.             // At this point we should have a non-null transparent proxy
  1158.             if (proxy == null)
  1159.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_UnexpectedNullTP")));
  1160.            
  1161.             BCLDebug.Assert(IsTransparentProxy(proxy), "IsTransparentProxy(proxy)");
  1162.            
  1163.             Message.DebugOut("Leaving GetOrCreateProxy for given proxy\n");
  1164.             // Return the underlying transparent proxy
  1165.             return proxy;
  1166.         }
  1167.        
  1168.         //
  1169.         //
  1170.         // This version of GetOrCreateProxy is used for Connect(URI, type)
  1171.         private static object GetOrCreateProxy(Type classToProxy, Identity idObj)
  1172.         {
  1173.             Message.DebugOut("Entering GetOrCreateProxy for given class\n");
  1174.            
  1175.             object proxy = idObj.TPOrObject;
  1176.             if (null == proxy) {
  1177.                 // Create the proxy
  1178.                 proxy = SetOrCreateProxy(idObj, classToProxy, null);
  1179.             }
  1180.             // proxy from idObj may be non-null if we are doing a Connect
  1181.             // under new XXX() ... also if we are connecting to a remote URL
  1182.             // which we previously connected.
  1183.            
  1184.             // If we are in the same domain as the server object then we
  1185.             // can check for type compatibility of the proxy with the given
  1186.             // type. Otherwise, we will defer this check to method call time.
  1187.             // If we do not do this now then we run the risk of returning
  1188.             // a proxy which is different from the type given.
  1189.            
  1190.             ServerIdentity serverID = idObj as ServerIdentity;
  1191.             if (null != serverID) {
  1192.                 // Check for type compatibility
  1193.                 Type serverType = serverID.ServerType;
  1194.                 if (!classToProxy.IsAssignableFrom(serverType)) {
  1195.                     throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_FromTo"), serverType.FullName, classToProxy.FullName));
  1196.                 }
  1197.                
  1198.             }
  1199.            
  1200.             // At this point we should have a non-null transparent proxy
  1201.             BCLDebug.Assert(null != proxy && IsTransparentProxy(proxy), "null != proxy && IsTransparentProxy(proxy)");
  1202.            
  1203.             Message.DebugOut("Leaving GetOrCreateProxy for given class\n");
  1204.             return proxy;
  1205.         }
  1206.        
  1207.        
  1208.        
  1209.         private static MarshalByRefObject SetOrCreateProxy(Identity idObj, Type classToProxy, object proxy)
  1210.         {
  1211.             Message.DebugOut("Entering SetOrCreateProxy for type \n");
  1212.            
  1213.             RealProxy realProxy = null;
  1214.             // If a proxy has not been supplied create one
  1215.             if (null == proxy) {
  1216.                 // Create a remoting proxy
  1217.                 Message.DebugOut("SetOrCreateProxy::Creating Proxy for " + classToProxy.FullName + "\n");
  1218.                
  1219.                 ServerIdentity srvID = idObj as ServerIdentity;
  1220.                 if (idObj.ObjectRef != null) {
  1221.                     ProxyAttribute pa = ActivationServices.GetProxyAttribute(classToProxy);
  1222.                     realProxy = pa.CreateProxy(idObj.ObjectRef, classToProxy, null, null);
  1223.                 }
  1224.                 if (null == realProxy) {
  1225.                     // The custom proxy attribute does not want to create a proxy. We create a default
  1226.                     // proxy in this case.
  1227.                     ProxyAttribute defaultProxyAttribute = ActivationServices.DefaultProxyAttribute;
  1228.                    
  1229.                     realProxy = defaultProxyAttribute.CreateProxy(idObj.ObjectRef, classToProxy, null, (null == srvID ? null : srvID.ServerContext));
  1230.                 }
  1231.             }
  1232.             else {
  1233.                 BCLDebug.Assert(IsTransparentProxy(proxy), "IsTransparentProxy(proxy)");
  1234.                
  1235.                 // Extract the remoting proxy from the transparent proxy
  1236.                 Message.DebugOut("SetOrCreateProxy::Proxy already created \n");
  1237.                 realProxy = GetRealProxy(proxy);
  1238.             }
  1239.            
  1240.             BCLDebug.Assert(null != realProxy, "null != realProxy");
  1241.            
  1242.             // Set the back reference to the identity in the proxy object
  1243.             realProxy.IdentityObject = idObj;
  1244.            
  1245.             // Set the reference to the proxy in the identity object
  1246.             proxy = realProxy.GetTransparentProxy();
  1247.             proxy = idObj.RaceSetTransparentProxy(proxy);
  1248.            
  1249.             Message.DebugOut("Leaving SetOrCreateProxy\n");
  1250.             // return the transparent proxy
  1251.             return (MarshalByRefObject)proxy;
  1252.         }
  1253.        
  1254.         // Check
  1255.         private static bool AreChannelDataElementsNull(object[] channelData)
  1256.         {
  1257.             foreach (object o in channelData) {
  1258.                 if (o != null)
  1259.                     return false;
  1260.             }
  1261.            
  1262.             return true;
  1263.            
  1264.         }
  1265.        
  1266.         static internal void CreateEnvoyAndChannelSinks(MarshalByRefObject tpOrObject, ObjRef objectRef, out IMessageSink chnlSink, out IMessageSink envoySink)
  1267.         {
  1268.            
  1269.             Message.DebugOut("Creating envoy and channel sinks \n");
  1270.             BCLDebug.Assert(((null != tpOrObject) || (null != objectRef)), "((null != tpOrObject) || (null != objectRef)");
  1271.            
  1272.             // Set the out parameters
  1273.             chnlSink = null;
  1274.             envoySink = null;
  1275.            
  1276.             if (null == objectRef) {
  1277.                 // If the objectRef is not present this is a cross context case
  1278.                 // and we should set the cross context channel sink
  1279.                 chnlSink = ChannelServices.GetCrossContextChannelSink();
  1280.                
  1281.                 envoySink = Thread.CurrentContext.CreateEnvoyChain(tpOrObject);
  1282.             }
  1283.             else {
  1284.                 // Extract the channel from the channel data and name embedded
  1285.                 // inside the objectRef
  1286.                 object[] channelData = objectRef.ChannelInfo.ChannelData;
  1287.                 if (channelData != null && !AreChannelDataElementsNull(channelData)) {
  1288.                     for (int i = 0; i < channelData.Length; i++) {
  1289.                         // Get the first availabe sink
  1290.                         chnlSink = ChannelServices.CreateMessageSink(channelData[i]);
  1291.                         if (null != chnlSink) {
  1292.                             break;
  1293.                         }
  1294.                     }
  1295.                    
  1296.                    
  1297.                     // if chnkSink is still null, try to find a channel that can service
  1298.                     // this uri.
  1299.                     if (null == chnlSink) {
  1300.                         // NOTE: careful! we are calling user code here after holding
  1301.                         // the delayLoadChannelLock (channel ctor-s for arbitrary channels
  1302.                         // will run while the lock is held).
  1303.                         lock (s_delayLoadChannelLock) {
  1304.                             // Check once to ensure that noone beat us in a race
  1305.                             for (int i = 0; i < channelData.Length; i++) {
  1306.                                 // Get the first availabe sink
  1307.                                 chnlSink = ChannelServices.CreateMessageSink(channelData[i]);
  1308.                                 if (null != chnlSink) {
  1309.                                     break;
  1310.                                 }
  1311.                             }
  1312.                            
  1313.                            
  1314.                             if (null == chnlSink) {
  1315.                                 // We don't have a sink
  1316.                                 foreach (object data in channelData) {
  1317.                                     string objectURI;
  1318.                                     chnlSink = RemotingConfigHandler.FindDelayLoadChannelForCreateMessageSink(null, data, out objectURI);
  1319.                                     if (null != chnlSink)
  1320.                                         break;
  1321.                                 }
  1322.                             }
  1323.                         }
  1324.                     }
  1325.                 }
  1326.                
  1327.                 // Extract the envoy sinks from the objectRef
  1328.                 if ((null != objectRef.EnvoyInfo) && (null != objectRef.EnvoyInfo.EnvoySinks)) {
  1329.                     envoySink = objectRef.EnvoyInfo.EnvoySinks;
  1330.                 }
  1331.                 else {
  1332.                     envoySink = EnvoyTerminatorSink.MessageSink;
  1333.                 }
  1334.             }
  1335.         }
  1336.        
  1337.         static internal string CreateEnvoyAndChannelSinks(string url, object data, out IMessageSink chnlSink, out IMessageSink envoySink)
  1338.         {
  1339.             BCLDebug.Assert(null != url, "null != url");
  1340.             string objectURI = null;
  1341.            
  1342.             objectURI = CreateChannelSink(url, data, out chnlSink);
  1343.            
  1344.             envoySink = EnvoyTerminatorSink.MessageSink;
  1345.            
  1346.             return objectURI;
  1347.         }
  1348.        
  1349.         private static string CreateChannelSink(string url, object data, out IMessageSink chnlSink)
  1350.         {
  1351.             BCLDebug.Assert(null != url, "null != url");
  1352.             string objectURI = null;
  1353.            
  1354.             chnlSink = ChannelServices.CreateMessageSink(url, data, out objectURI);
  1355.            
  1356.             // if chnkSink is still null, try to find a channel that can service this uri.
  1357.             if (null == chnlSink) {
  1358.                 lock (s_delayLoadChannelLock) {
  1359.                     chnlSink = ChannelServices.CreateMessageSink(url, data, out objectURI);
  1360.                     if (null == chnlSink) {
  1361.                         chnlSink = RemotingConfigHandler.FindDelayLoadChannelForCreateMessageSink(url, data, out objectURI);
  1362.                     }
  1363.                 }
  1364.             }
  1365.            
  1366.             return objectURI;
  1367.         }
  1368.         // CreateChannelSinks
  1369.         static internal void SetEnvoyAndChannelSinks(Identity idObj, IMessageSink chnlSink, IMessageSink envoySink)
  1370.         {
  1371.             Message.DebugOut("Setting up envoy and channel sinks \n");
  1372.             BCLDebug.Assert(null != idObj, "null != idObj");
  1373.            
  1374.             // Decide if we need to set the envoy sink chain
  1375.             if (null == idObj.ChannelSink) {
  1376.                 if (null != chnlSink) {
  1377.                     idObj.RaceSetChannelSink(chnlSink);
  1378.                 }
  1379.             }
  1380.            
  1381.             // Decide if we need to set the envoy sink chain
  1382.             if (null == idObj.EnvoyChain) {
  1383.                 if (null != envoySink) {
  1384.                     idObj.RaceSetEnvoyChain(envoySink);
  1385.                 }
  1386.                 else {
  1387.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadInternalState_FailEnvoySink")));
  1388.                 }
  1389.             }
  1390.         }
  1391.        
  1392.         // Check whether the transparent proxy backing the real proxy
  1393.         // is assignable from the given type.
  1394.         private static bool CheckCast(RealProxy rp, Type castType)
  1395.         {
  1396.             // NOTE: This is the point where JIT_CheckCastClass ultimately
  1397.             // lands up in the managed world if the object being cast is
  1398.             // a transparent proxy.
  1399.             // If we are here, it means that walking the current EEClass
  1400.             // up the chain inside the EE was unable to verify the cast.
  1401.            
  1402.             Message.DebugOut("Entered CheckCast for type " + castType);
  1403.             bool fCastOK = false;
  1404.            
  1405.             BCLDebug.Assert(rp != null, "Shouldn't be called with null real proxy.");
  1406.            
  1407.             // Always return true if cast is to System.Object
  1408.             if (castType == typeof(object))
  1409.                 return true;
  1410.            
  1411.             // We do not allow casting to non-interface types that do not extend
  1412.             // from System.MarshalByRefObject
  1413.             if (!castType.IsInterface && !castType.IsMarshalByRef)
  1414.                 return false;
  1415.            
  1416.             if (castType != typeof(IObjectReference)) {
  1417.                 IRemotingTypeInfo typeInfo = rp as IRemotingTypeInfo;
  1418.                 if (null != typeInfo) {
  1419.                     fCastOK = typeInfo.CanCastTo(castType, rp.GetTransparentProxy());
  1420.                 }
  1421.                 else {
  1422.                     // The proxy does not implement IRemotingTypeInfo, so we should
  1423.                     // try to do casting based on the ObjRef type info.
  1424.                     Identity id = rp.IdentityObject;
  1425.                     if (id != null) {
  1426.                         ObjRef objRef = id.ObjectRef;
  1427.                         if (objRef != null) {
  1428.                             typeInfo = objRef.TypeInfo;
  1429.                             if (typeInfo != null) {
  1430.                                 fCastOK = typeInfo.CanCastTo(castType, rp.GetTransparentProxy());
  1431.                             }
  1432.                         }
  1433.                     }
  1434.                 }
  1435.             }
  1436.            
  1437.             Message.DebugOut("CheckCast returning " + fCastOK);
  1438.             return fCastOK;
  1439.         }
  1440.        
  1441.         static internal bool ProxyCheckCast(RealProxy rp, Type castType)
  1442.         {
  1443.             return CheckCast(rp, castType);
  1444.         }
  1445.         // ProxyCheckCast
  1446. /*
  1447.         **CheckCast
  1448.         **Action:  When a proxy to an object is serialized, the MethodTable is only
  1449.         **        expanded on an on-demand basis.  For purely managed operations, this
  1450.         **        happens in a transparent fashion.  However, for delegates (and
  1451.         **        potentially other types) we need to force this expansion to happen.
  1452.         **Returns: The newly expanded object.  Returns the identity if no expansion is required.
  1453.         **Arguments: objToExpand -- The object to be expanded.
  1454.         **          type -- the type to which to expand it.
  1455.         **Exceptions: None.
  1456.         */       
  1457.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1458.         static internal extern object CheckCast(object objToExpand, Type type);
  1459.        
  1460.         static internal GCHandle CreateDelegateInvocation(WaitCallback waitDelegate, object state)
  1461.         {
  1462.             object[] delegateCallToken = new object[2];
  1463.             delegateCallToken[0] = waitDelegate;
  1464.             delegateCallToken[1] = state;
  1465.             return System.Runtime.InteropServices.GCHandle.Alloc(delegateCallToken);
  1466.         }
  1467.        
  1468.         static internal void DisposeDelegateInvocation(GCHandle delegateCallToken)
  1469.         {
  1470.             delegateCallToken.Free();
  1471.         }
  1472.        
  1473.         static internal object CreateProxyForDomain(int appDomainId, IntPtr defCtxID)
  1474.         {
  1475.             AppDomain proxy = null;
  1476.            
  1477.             ObjRef objRef = CreateDataForDomain(appDomainId, defCtxID);
  1478.            
  1479.             // Unmarshal the objref in the old app domain
  1480.             proxy = (AppDomain)Unmarshal(objRef);
  1481.            
  1482.             return proxy;
  1483.         }
  1484.         // CreateProxyForDomain
  1485.         static internal object CreateDataForDomainCallback(object[] args)
  1486.         {
  1487.             // Ensure that the well known channels are registered in this domain too
  1488.             RegisterWellKnownChannels();
  1489.            
  1490.             // Marshal the app domain object
  1491.             ObjRef objref = MarshalInternal(Thread.CurrentContext.AppDomain, null, null, false);
  1492.            
  1493.             ServerIdentity si = (ServerIdentity)MarshalByRefObject.GetIdentity(Thread.CurrentContext.AppDomain);
  1494.             si.SetHandle();
  1495.             objref.SetServerIdentity(si.GetHandle());
  1496.             objref.SetDomainID(AppDomain.CurrentDomain.GetId());
  1497.             return objref;
  1498.         }
  1499.        
  1500.         static internal ObjRef CreateDataForDomain(int appDomainId, IntPtr defCtxID)
  1501.         {
  1502.             // This is a subroutine of CreateProxyForDomain
  1503.             // so we can segregate the object references
  1504.             // from different app domains into different frames. This is
  1505.             // important for the app domain leak checking code.
  1506.            
  1507.             Message.DebugOut("Creating proxy for domain " + appDomainId + "\n");
  1508.            
  1509.             RegisterWellKnownChannels();
  1510.            
  1511.             InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(CreateDataForDomainCallback);
  1512.            
  1513.             return (ObjRef)Thread.CurrentThread.InternalCrossContextCallback(null, defCtxID, appDomainId, xctxDel, null);
  1514.            
  1515.         }
  1516.         // CreateDataForDomain
  1517.        
  1518.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  1519.         public static MethodBase GetMethodBaseFromMethodMessage(IMethodMessage msg)
  1520.         {
  1521.             MethodBase mb = InternalGetMethodBaseFromMethodMessage(msg);
  1522.             return mb;
  1523.         }
  1524.        
  1525.         static internal MethodBase InternalGetMethodBaseFromMethodMessage(IMethodMessage msg)
  1526.         {
  1527.             if (null == msg) {
  1528.                 return null;
  1529.             }
  1530.            
  1531.             Type t = RemotingServices.InternalGetTypeFromQualifiedTypeName(msg.TypeName);
  1532.             if (t == null) {
  1533.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), msg.TypeName));
  1534.                
  1535.             }
  1536.            
  1537.             // Use the signature, type and method name to determine the
  1538.             // methodbase via reflection.
  1539.             Type[] signature = (Type[])msg.MethodSignature;
  1540.             return GetMethodBase(msg, t, signature);
  1541.         }
  1542.        
  1543.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  1544.         public static bool IsMethodOverloaded(IMethodMessage msg)
  1545.         {
  1546.             RemotingMethodCachedData cache = InternalRemotingServices.GetReflectionCachedData(msg.MethodBase);
  1547.            
  1548.             return cache.IsOverloaded();
  1549.         }
  1550.         // IsMethodOverloaded
  1551.        
  1552.         private static MethodBase GetMethodBase(IMethodMessage msg, Type t, Type[] signature)
  1553.         {
  1554.             MethodBase mb = null;
  1555.            
  1556.             // Get the reflection object depending on whether it is a
  1557.             // constructor call or a method call.
  1558.             if ((msg is IConstructionCallMessage) || (msg is IConstructionReturnMessage)) {
  1559.                 if ((null == signature)) {
  1560.                     BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with null sig ", msg.MethodName);
  1561.                     ConstructorInfo[] ci;
  1562.                     RuntimeType rt = t as RuntimeType;
  1563.                     if (rt == null)
  1564.                         ci = t.GetConstructors();
  1565.                     else
  1566.                         ci = rt.GetConstructors();
  1567.                    
  1568.                     if (1 != ci.Length) {
  1569.                         // There is more than one constructor defined but
  1570.                         // we do not have a signature to differentiate between
  1571.                         // them.
  1572.                         throw new AmbiguousMatchException(Environment.GetResourceString("Remoting_AmbiguousCTOR"));
  1573.                     }
  1574.                     mb = ci[0];
  1575.                 }
  1576.                 else {
  1577.                     BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg.MethodName, " ", signature.Length);
  1578.                     RuntimeType rt = t as RuntimeType;
  1579.                     if (rt == null)
  1580.                         mb = t.GetConstructor(signature);
  1581.                     else
  1582.                         mb = rt.GetConstructor(signature);
  1583.                 }
  1584.             }
  1585.             else if ((msg is IMethodCallMessage) || (msg is IMethodReturnMessage)) {
  1586.                 // We demand reflection permission in the api that calls this
  1587.                 // for non-public types
  1588.                 if (null == signature) {
  1589.                     BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with null sig ", msg.MethodName);
  1590.                     RuntimeType rt = t as RuntimeType;
  1591.                     if (rt == null)
  1592.                         mb = t.GetMethod(msg.MethodName, RemotingServices.LookupAll);
  1593.                     else
  1594.                         mb = rt.GetMethod(msg.MethodName, RemotingServices.LookupAll);
  1595.                 }
  1596.                 else {
  1597.                     BCLDebug.Trace("REMOTE", "RemotingServices.MethodBaseFromMethodCallMessage with non-null sig ", msg.MethodName, " ", signature.Length);
  1598.                     RuntimeType rt = t as RuntimeType;
  1599.                     if (rt == null)
  1600.                         mb = t.GetMethod(msg.MethodName, RemotingServices.LookupAll, null, signature, null);
  1601.                     else
  1602.                         mb = rt.GetMethod(msg.MethodName, RemotingServices.LookupAll, null, CallingConventions.Any, signature, null);
  1603.                 }
  1604.                
  1605.             }
  1606.            
  1607.             return mb;
  1608.         }
  1609.        
  1610.         static internal bool IsMethodAllowedRemotely(MethodBase method)
  1611.         {
  1612.             // MarhsalByRefObject.InvokeMember is allowed to be invoked remotely. It is a wrapper for a com method as represented in managed
  1613.             // 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
  1614.             // the tlbimpl will only generate methods which can be invoked remotely.
  1615.            
  1616.             if (s_FieldGetterMB == null || s_FieldSetterMB == null || s_IsInstanceOfTypeMB == null || s_InvokeMemberMB == null || s_CanCastToXmlTypeMB == null) {
  1617.                 System.Security.CodeAccessPermission.AssertAllPossible();
  1618.                 if (s_FieldGetterMB == null)
  1619.                     s_FieldGetterMB = typeof(object).GetMethod(FieldGetterName, RemotingServices.LookupAll);
  1620.                
  1621.                 if (s_FieldSetterMB == null)
  1622.                     s_FieldSetterMB = typeof(object).GetMethod(FieldSetterName, RemotingServices.LookupAll);
  1623.                
  1624.                 if (s_IsInstanceOfTypeMB == null) {
  1625.                     s_IsInstanceOfTypeMB = typeof(MarshalByRefObject).GetMethod(IsInstanceOfTypeName, RemotingServices.LookupAll);
  1626.                 }
  1627.                
  1628.                 if (s_CanCastToXmlTypeMB == null) {
  1629.                     s_CanCastToXmlTypeMB = typeof(MarshalByRefObject).GetMethod(CanCastToXmlTypeName, RemotingServices.LookupAll);
  1630.                 }
  1631.                
  1632.                 if (s_InvokeMemberMB == null) {
  1633.                     s_InvokeMemberMB = typeof(MarshalByRefObject).GetMethod(InvokeMemberName, RemotingServices.LookupAll);
  1634.                 }
  1635.             }
  1636.            
  1637.             return method == s_FieldGetterMB || method == s_FieldSetterMB || method == s_IsInstanceOfTypeMB || method == s_InvokeMemberMB || method == s_CanCastToXmlTypeMB;
  1638.         }
  1639.        
  1640.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  1641.         public static bool IsOneWay(MethodBase method)
  1642.         {
  1643.             if (method == null)
  1644.                 return false;
  1645.            
  1646.             RemotingMethodCachedData cache = InternalRemotingServices.GetReflectionCachedData(method);
  1647.            
  1648.             return cache.IsOneWayMethod();
  1649.         }
  1650.        
  1651.         // Given a method base object, see if we can find an async version of the
  1652.         // method on the same class.
  1653.         static internal bool FindAsyncMethodVersion(MethodInfo method, out MethodInfo beginMethod, out MethodInfo endMethod)
  1654.         {
  1655.             beginMethod = null;
  1656.             endMethod = null;
  1657.            
  1658.             // determine names of Begin/End versions
  1659.             string beginName = "Begin" + method.Name;
  1660.             string endName = "End" + method.Name;
  1661.            
  1662.             // determine parameter lists for Begin/End versions
  1663.             ArrayList beginParameters = new ArrayList();
  1664.             ArrayList endParameters = new ArrayList();
  1665.            
  1666.             Type beginReturnType = typeof(IAsyncResult);
  1667.             Type endReturnType = method.ReturnType;
  1668.            
  1669.             ParameterInfo[] paramList = method.GetParameters();
  1670.             foreach (ParameterInfo param in paramList) {
  1671.                 if (param.IsOut)
  1672.                     endParameters.Add(param);
  1673.                 else if (param.ParameterType.IsByRef) {
  1674.                     beginParameters.Add(param);
  1675.                     endParameters.Add(param);
  1676.                 }
  1677.                 else {
  1678.                     // it's an in parameter
  1679.                     beginParameters.Add(param);
  1680.                 }
  1681.             }
  1682.            
  1683.             beginParameters.Add(typeof(AsyncCallback));
  1684.             beginParameters.Add(typeof(object));
  1685.             endParameters.Add(typeof(IAsyncResult));
  1686.            
  1687.             // try to match these signatures with the methods on the type
  1688.             Type type = method.DeclaringType;
  1689.             MethodInfo[] methods = type.GetMethods();
  1690.            
  1691.             foreach (MethodInfo mi in methods) {
  1692.                 ParameterInfo[] parameterList = mi.GetParameters();
  1693.                
  1694.                 // see if return value is IAsyncResult
  1695.                
  1696.                 if (mi.Name.Equals(beginName) && (mi.ReturnType == beginReturnType) && CompareParameterList(beginParameters, parameterList)) {
  1697.                     beginMethod = mi;
  1698.                 }
  1699.                 else if (mi.Name.Equals(endName) && (mi.ReturnType == endReturnType) && CompareParameterList(endParameters, parameterList)) {
  1700.                     endMethod = mi;
  1701.                 }
  1702.             }
  1703.            
  1704.             if ((beginMethod != null) && (endMethod != null))
  1705.                 return true;
  1706.             else
  1707.                 return false;
  1708.         }
  1709.         // FindAsyncMethodVersion
  1710.        
  1711.         // Helper function for FindAsyncMethodVersion
  1712.         private static bool CompareParameterList(ArrayList params1, ParameterInfo[] params2)
  1713.         {
  1714.             // params1 contains a list of parameters (and possibly some types which are
  1715.             // assumed to be in parameters)
  1716.             // param2 just contains the list of parameters from some method
  1717.            
  1718.             if (params1.Count != params2.Length)
  1719.                 return false;
  1720.            
  1721.             int co = 0;
  1722.             foreach (object obj in params1) {
  1723.                 ParameterInfo param = params2[co];
  1724.                
  1725.                 ParameterInfo pi = obj as ParameterInfo;
  1726.                 if (null != pi) {
  1727.                     if ((pi.ParameterType != param.ParameterType) || (pi.IsIn != param.IsIn) || (pi.IsOut != param.IsOut)) {
  1728.                         return false;
  1729.                     }
  1730.                 }
  1731.                 else if (((Type)obj != param.ParameterType) && param.IsIn)
  1732.                     return false;
  1733.                 co++;
  1734.             }
  1735.            
  1736.             return true;
  1737.         }
  1738.         // CompareParameterList
  1739.        
  1740.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  1741.         public static Type GetServerTypeForUri(string URI)
  1742.         {
  1743.             Type svrType = null;
  1744.            
  1745.             if (null != URI) {
  1746.                 ServerIdentity srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI);
  1747.                
  1748.                 if (null == srvID) {
  1749.                     // Check if this a well-known object which needs to be faulted in
  1750.                     svrType = RemotingConfigHandler.GetServerTypeForUri(URI);
  1751.                 }
  1752.                 else {
  1753.                     svrType = srvID.ServerType;
  1754.                 }
  1755.             }
  1756.            
  1757.             return svrType;
  1758.         }
  1759.        
  1760.        
  1761.         // This method is called after an appdomain is unloaded from the
  1762.         // current domain.
  1763.         static internal void DomainUnloaded(Int32 domainID)
  1764.         {
  1765.             // Remove any client side identities, presumably the driver
  1766.             // domain has released all references to proxies in the unloaded
  1767.             // domain.
  1768.             IdentityHolder.FlushIdentityTable();
  1769.             // Remove the cross domain channel sink for the unloaded domain
  1770.             CrossAppDomainSink.DomainUnloaded(domainID);
  1771.         }
  1772.        
  1773.         // This method is called from the VM and helps the appdomain
  1774.         // folks to get to the server appdomain from a proxy. This is
  1775.         // expected to be called on strictly cross domain proxies.
  1776.         //
  1777.         // This returns the unmanaged context object for the proxy.
  1778.         // We fetch the appDomain out of the context in the VM.
  1779.         // This will return NULL (or 0) if the server for the proxy is
  1780.         // not from this process or if the server domain is invalid
  1781.         // or if there is not enough information to determine the server
  1782.         // context.
  1783.         static internal IntPtr GetServerContextForProxy(object tp)
  1784.         {
  1785.             ObjRef objRef = null;
  1786.             bool bSameDomain;
  1787.             int domainId;
  1788.             return GetServerContextForProxy(tp, out objRef, out bSameDomain, out domainId);
  1789.         }
  1790.        
  1791.         // This returns the domain ID if the proxy is from this process
  1792.         // whether or not the domain is valid!
  1793.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  1794.         static internal int GetServerDomainIdForProxy(object tp)
  1795.         {
  1796.             BCLDebug.Assert(IsTransparentProxy(tp), "Must be called only for TPs");
  1797.             RealProxy rp = GetRealProxy(tp);
  1798.             Identity id = rp.IdentityObject;
  1799.             return id.ObjectRef.GetServerDomainId();
  1800.            
  1801.         }
  1802.        
  1803.         // This will retrieve the server domain and context id
  1804.         static internal void GetServerContextAndDomainIdForProxy(object tp, out IntPtr contextId, out int domainId)
  1805.         {
  1806.             ObjRef objRef;
  1807.             bool bSameDomain;
  1808.             contextId = GetServerContextForProxy(tp, out objRef, out bSameDomain, out domainId);
  1809.         }
  1810.         // GetServerContextAndDomainIdForProxy
  1811.        
  1812.         // This is a helper for the methods above.
  1813.         // NOTE:: Returns the unmanaged server context for a proxy
  1814.         // This is *NOT* the same as "public int Context::ContextID"
  1815.         private static IntPtr GetServerContextForProxy(object tp, out ObjRef objRef, out bool bSameDomain, out int domainId)
  1816.         {
  1817.             // Note: the contextId we return from here should be the address
  1818.             // of the unmanaged (VM) context object or NULL.
  1819.            
  1820.             IntPtr contextId = IntPtr.Zero;
  1821.             objRef = null;
  1822.             bSameDomain = false;
  1823.             domainId = 0;
  1824.             if (IsTransparentProxy(tp)) {
  1825.                 // This is a transparent proxy. Try to obtain the backing
  1826.                 // RealProxy from it.
  1827.                 RealProxy rp = GetRealProxy(tp);
  1828.                
  1829.                 // Get the identity from the realproxy
  1830.                 Identity id = rp.IdentityObject;
  1831.                 if (null != id) {
  1832.                     ServerIdentity serverID = id as ServerIdentity;
  1833.                     if (null != serverID) {
  1834.                         // We are in the app domain of the server
  1835.                         bSameDomain = true;
  1836.                         contextId = serverID.ServerContext.InternalContextID;
  1837.                         domainId = Thread.GetDomain().GetId();
  1838.                     }
  1839.                     else {
  1840.                         // Server is from another app domain
  1841.                         // (possibly from another process)
  1842.                         objRef = id.ObjectRef;
  1843.                         if (objRef != null) {
  1844.                             contextId = objRef.GetServerContext(out domainId);
  1845.                         }
  1846.                         else {
  1847.                             // Proxy does not have an associated ObjRef
  1848.                            
  1849.                             //BCLDebug.Assert(false, "Found proxy without an objref");
  1850.                             contextId = IntPtr.Zero;
  1851.                         }
  1852.                     }
  1853.                 }
  1854.                 else {
  1855.                     // This was probably a custom proxy other than RemotingProxy
  1856.                     BCLDebug.Assert(!(rp is RemotingProxy), "!(rp is RemotingProxy)");
  1857.                    
  1858.                     contextId = Context.DefaultContext.InternalContextID;
  1859.                 }
  1860.             }
  1861.            
  1862.             return contextId;
  1863.         }
  1864.        
  1865.         // Return the server context of the object provided if the object
  1866.         // was born in the current appdomain, else return null.
  1867.         //
  1868.         // NOTE: This returns the managed context object that the server
  1869.         // is associated with ...
  1870.         static internal Context GetServerContext(MarshalByRefObject obj)
  1871.         {
  1872.             Context serverCtx = null;
  1873.            
  1874.             if (!IsTransparentProxy(obj) && (obj is ContextBoundObject)) {
  1875.                 // The object is native to the current context.
  1876.                 serverCtx = Thread.CurrentContext;
  1877.             }
  1878.             else {
  1879.                 RealProxy rp = GetRealProxy(obj);
  1880.                 Identity id = rp.IdentityObject;
  1881.                 ServerIdentity serverID = id as ServerIdentity;
  1882.                 if (null != serverID) {
  1883.                     // The object was born in the current appdomain.
  1884.                     // Extract the server context.
  1885.                     serverCtx = serverID.ServerContext;
  1886.                 }
  1887.             }
  1888.            
  1889.             return serverCtx;
  1890.         }
  1891.        
  1892.         // Return the actual type of the server object given the proxy
  1893.         //
  1894.         //
  1895.         private static object GetType(object tp)
  1896.         {
  1897.             BCLDebug.Assert(IsTransparentProxy(tp), "IsTransparentProxy(tp)");
  1898.            
  1899.             Type serverType = null;
  1900.            
  1901.             RealProxy rp = GetRealProxy(tp);
  1902.             Identity id = rp.IdentityObject;
  1903.             BCLDebug.Assert(!(id is ServerIdentity), "(!id is ServerIdentity)");
  1904.             if ((null != id) && (null != id.ObjectRef) && (null != id.ObjectRef.TypeInfo)) {
  1905.                 IRemotingTypeInfo serverTypeInfo = id.ObjectRef.TypeInfo;
  1906.                 string typeName = serverTypeInfo.TypeName;
  1907.                 if (typeName != null) {
  1908.                     serverType = InternalGetTypeFromQualifiedTypeName(typeName);
  1909.                 }
  1910.             }
  1911.            
  1912.             return serverType;
  1913.         }
  1914.        
  1915.        
  1916.         static internal byte[] MarshalToBuffer(object o)
  1917.         {
  1918.             // serialize headers and args together using the binary formatter
  1919.             MemoryStream stm = new MemoryStream();
  1920.             RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
  1921.             BinaryFormatter fmt = new BinaryFormatter();
  1922.             fmt.SurrogateSelector = ss;
  1923.             fmt.Context = new StreamingContext(StreamingContextStates.Other);
  1924.                 /* No Security check */            fmt.Serialize(stm, o, null, false);
  1925.            
  1926.             return stm.GetBuffer();
  1927.         }
  1928.        
  1929.         static internal object UnmarshalFromBuffer(byte[] b)
  1930.         {
  1931.             MemoryStream stm = new MemoryStream(b);
  1932.             BinaryFormatter fmt = new BinaryFormatter();
  1933.             fmt.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
  1934.             //*******Add this line
  1935.             fmt.SurrogateSelector = null;
  1936.             fmt.Context = new StreamingContext(StreamingContextStates.Other);
  1937.                 /* No Security check */            object o = fmt.Deserialize(stm, null, false);
  1938.             return o;
  1939.         }
  1940.        
  1941.         static internal object UnmarshalReturnMessageFromBuffer(byte[] b, IMethodCallMessage msg)
  1942.         {
  1943.             MemoryStream stm = new MemoryStream(b);
  1944.             BinaryFormatter fmt = new BinaryFormatter();
  1945.             fmt.SurrogateSelector = null;
  1946.             fmt.Context = new StreamingContext(StreamingContextStates.Other);
  1947.             object o = fmt.DeserializeMethodResponse(stm, null, (IMethodCallMessage)msg);
  1948.             //= fmt.Deserialize(stm, null, false /* No Security check */);
  1949.             return o;
  1950.         }
  1951.        
  1952.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  1953.         public static IMethodReturnMessage ExecuteMessage(MarshalByRefObject target, IMethodCallMessage reqMsg)
  1954.         {
  1955.             // Argument validation
  1956.             if (null == target) {
  1957.                 throw new ArgumentNullException("target");
  1958.             }
  1959.            
  1960.             RealProxy rp = GetRealProxy(target);
  1961.            
  1962.             // Check for context match
  1963.             if (rp is RemotingProxy && !rp.DoContextsMatch()) {
  1964.                 throw new RemotingException(Environment.GetResourceString("Remoting_Proxy_WrongContext"));
  1965.             }
  1966.            
  1967.             // Dispatch the message
  1968.             StackBuilderSink dispatcher = new StackBuilderSink(target);
  1969.            
  1970.             // dispatch the message
  1971.             IMethodReturnMessage retMsg = (IMethodReturnMessage)dispatcher.SyncProcessMessage(reqMsg, 0, true);
  1972.            
  1973.             return retMsg;
  1974.         }
  1975.         // ExecuteMessage
  1976.        
  1977.        
  1978.         //
  1979.         // Methods for mapping and resolving qualified type names
  1980.         // A qualified type name describes the name that we use in the ObjRef and
  1981.         // message TypeName. It consists either of the actual type name or
  1982.         // "<typeId>:typename" where for now "soap:<soap type name>" is the only
  1983.         // supported alternative.
  1984.         //
  1985.        
  1986.         // This is used by the cached type data to figure out which type name
  1987.         // to use (this should never be publicly exposed; GetDefaultQualifiedTypeName should,
  1988.         // if anything at all)
  1989.         static internal string DetermineDefaultQualifiedTypeName(Type type)
  1990.         {
  1991.             if (type == null)
  1992.                 throw new ArgumentNullException("type");
  1993.            
  1994.             // see if there is an xml type name
  1995.             string xmlTypeName = null;
  1996.             string xmlTypeNamespace = null;
  1997.             if (SoapServices.GetXmlTypeForInteropType(type, out xmlTypeName, out xmlTypeNamespace)) {
  1998.                 return "soap:" + xmlTypeName + ", " + xmlTypeNamespace;
  1999.             }
  2000.            
  2001.             // there are no special mappings, so use the fully qualified CLR type name
  2002.             return type.AssemblyQualifiedName;
  2003.         }
  2004.         // DetermineDefaultQualifiedTypeName
  2005.        
  2006.         // retrieves type name from the cache data which uses DetermineDefaultQualifiedTypeName
  2007.         static internal string GetDefaultQualifiedTypeName(Type type)
  2008.         {
  2009.             RemotingTypeCachedData cache = (RemotingTypeCachedData)InternalRemotingServices.GetReflectionCachedData(type);
  2010.            
  2011.             return cache.QualifiedTypeName;
  2012.         }
  2013.         // GetDefaultQualifiedTypeName
  2014.        
  2015.         static internal string InternalGetClrTypeNameFromQualifiedTypeName(string qualifiedTypeName)
  2016.         {
  2017.             // look to see if this is a clr type name
  2018.             // length of "clr:"
  2019.             if (qualifiedTypeName.Length > 4) {
  2020.                 if (String.CompareOrdinal(qualifiedTypeName, 0, "clr:", 0, 4) == 0) {
  2021.                     // strip "clr:" off the front
  2022.                     string actualTypeName = qualifiedTypeName.Substring(4);
  2023.                     return actualTypeName;
  2024.                 }
  2025.             }
  2026.             return null;
  2027.         }
  2028.        
  2029.         private static int IsSoapType(string qualifiedTypeName)
  2030.         {
  2031.             // look to see if this is a soap type name
  2032.             // length of "soap:"
  2033.             if (qualifiedTypeName.Length > 5) {
  2034.                 if (String.CompareOrdinal(qualifiedTypeName, 0, "soap:", 0, 5) == 0) {
  2035.                     // find comma starting from just past "soap:"
  2036.                     return qualifiedTypeName.IndexOf(',', 5);
  2037.                 }
  2038.             }
  2039.             return -1;
  2040.         }
  2041.        
  2042.         static internal string InternalGetSoapTypeNameFromQualifiedTypeName(string xmlTypeName, string xmlTypeNamespace)
  2043.         {
  2044.             // This must be the default encoding of the soap type (or the type wasn't
  2045.             // preloaded).
  2046.             string typeNamespace;
  2047.             string assemblyName;
  2048.             if (!SoapServices.DecodeXmlNamespaceForClrTypeNamespace(xmlTypeNamespace, out typeNamespace, out assemblyName)) {
  2049.                 return null;
  2050.             }
  2051.            
  2052.             string typeName;
  2053.             if ((typeNamespace != null) && (typeNamespace.Length > 0))
  2054.                 typeName = typeNamespace + "." + xmlTypeName;
  2055.             else
  2056.                 typeName = xmlTypeName;
  2057.            
  2058.             try {
  2059.                 string fullTypeName = typeName + ", " + assemblyName;
  2060.                 return fullTypeName;
  2061.             }
  2062.             catch {
  2063.                 // We ignore errors and will just return null below since the type
  2064.                 // isn't set.
  2065.             }
  2066.             return null;
  2067.         }
  2068.        
  2069.         static internal string InternalGetTypeNameFromQualifiedTypeName(string qualifiedTypeName)
  2070.         {
  2071.             if (qualifiedTypeName == null)
  2072.                 throw new ArgumentNullException("qualifiedTypeName");
  2073.            
  2074.             string decodedName = InternalGetClrTypeNameFromQualifiedTypeName(qualifiedTypeName);
  2075.             if (decodedName != null) {
  2076.                 return decodedName;
  2077.             }
  2078.             int index = IsSoapType(qualifiedTypeName);
  2079.             if (index != -1) {
  2080.                 // This is a soap type name. We need to parse it and try to
  2081.                 // find the actual type. Format is "soap:xmlTypeName, xmlTypeNamespace"
  2082.                
  2083.                 string xmlTypeName = qualifiedTypeName.Substring(5, index - 5);
  2084.                 // +2 is to skip the comma and following space
  2085.                 string xmlTypeNamespace = qualifiedTypeName.Substring(index + 2, qualifiedTypeName.Length - (index + 2));
  2086.                
  2087.                 decodedName = InternalGetSoapTypeNameFromQualifiedTypeName(xmlTypeName, xmlTypeNamespace);
  2088.                 if (decodedName != null) {
  2089.                     return decodedName;
  2090.                 }
  2091.             }
  2092.             //no prefix return same
  2093.             return qualifiedTypeName;
  2094.            
  2095.         }
  2096.        
  2097.         // Retrieves type based on qualified type names. This does not do security checks
  2098.         // so don't expose this publicly (at least not directly). It returns null if the
  2099.         // type cannot be loaded.
  2100.         static internal Type InternalGetTypeFromQualifiedTypeName(string qualifiedTypeName, bool partialFallback)
  2101.         {
  2102.             if (qualifiedTypeName == null)
  2103.                 throw new ArgumentNullException("qualifiedTypeName");
  2104.            
  2105.             string decodedName = InternalGetClrTypeNameFromQualifiedTypeName(qualifiedTypeName);
  2106.             if (decodedName != null) {
  2107.                 return LoadClrTypeWithPartialBindFallback(decodedName, partialFallback);
  2108.             }
  2109.            
  2110.             int index = IsSoapType(qualifiedTypeName);
  2111.             if (index != -1) {
  2112.                 // This is a soap type name. We need to parse it and try to
  2113.                 // find the actual type. Format is "soap:xmlTypeName, xmlTypeNamespace"
  2114.                
  2115.                 string xmlTypeName = qualifiedTypeName.Substring(5, index - 5);
  2116.                 // +2 is to skip the comma and following space
  2117.                 string xmlTypeNamespace = qualifiedTypeName.Substring(index + 2, qualifiedTypeName.Length - (index + 2));
  2118.                
  2119.                 Type type = SoapServices.GetInteropTypeFromXmlType(xmlTypeName, xmlTypeNamespace);
  2120.                 if (type != null) {
  2121.                     return type;
  2122.                 }
  2123.                 decodedName = InternalGetSoapTypeNameFromQualifiedTypeName(xmlTypeName, xmlTypeNamespace);
  2124.                 if (decodedName != null) {
  2125.                     return LoadClrTypeWithPartialBindFallback(decodedName, true);
  2126.                 }
  2127.             }
  2128.            
  2129.             // There is no prefix, so assume this is a normal CLR type name.
  2130.             return LoadClrTypeWithPartialBindFallback(qualifiedTypeName, partialFallback);
  2131.         }
  2132.         // InternalGetTypeFromQualifiedTypeName
  2133.         static internal Type InternalGetTypeFromQualifiedTypeName(string qualifiedTypeName)
  2134.         {
  2135.             return InternalGetTypeFromQualifiedTypeName(qualifiedTypeName, true);
  2136.         }
  2137.        
  2138.         unsafe private static Type LoadClrTypeWithPartialBindFallback(string typeName, bool partialFallback)
  2139.         {
  2140.             // Try to load a type with fully qualified name if partialFallback is not requested
  2141.             if (!partialFallback) {
  2142.                 return Type.GetType(typeName, false);
  2143.             }
  2144.             else {
  2145.                 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  2146.                     /* hack */                return new RuntimeTypeHandle(RuntimeTypeHandle._GetTypeByName(typeName, false, false, false, ref stackMark, true)).GetRuntimeType();
  2147.             }
  2148.         }
  2149.         // LoadClrTypeWithPartialBindFallback
  2150.         //
  2151.         // end of Methods for mapping and resolving qualified type names
  2152.         //
  2153.        
  2154.        
  2155.         //
  2156.         // These are used by the profiling code to profile remoting.
  2157.         //
  2158.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2159.         static internal extern bool CORProfilerTrackRemoting();
  2160.        
  2161.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2162.         static internal extern bool CORProfilerTrackRemotingCookie();
  2163.        
  2164.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2165.         static internal extern bool CORProfilerTrackRemotingAsync();
  2166.        
  2167.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2168.         static internal extern void CORProfilerRemotingClientSendingMessage(out Guid id, bool fIsAsync);
  2169.        
  2170.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2171.         static internal extern void CORProfilerRemotingClientReceivingReply(Guid id, bool fIsAsync);
  2172.        
  2173.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2174.         static internal extern void CORProfilerRemotingServerReceivingMessage(Guid id, bool fIsAsync);
  2175.        
  2176.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2177.         static internal extern void CORProfilerRemotingServerSendingReply(out Guid id, bool fIsAsync);
  2178.        
  2179.         [System.Diagnostics.Conditional("REMOTING_PERF")]
  2180.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  2181.         [Obsolete("Use of this method is not recommended. The LogRemotingStage existed for internal diagnostic purposes only.")]
  2182.         public static void LogRemotingStage(int stage)
  2183.         {
  2184.         }
  2185.        
  2186.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2187.         static internal extern void ResetInterfaceCache(object proxy);
  2188.        
  2189.     }
  2190.     // RemotingServices
  2191.    
  2192.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  2193.     [System.Runtime.InteropServices.ComVisible(true)]
  2194.     public class InternalRemotingServices
  2195.     {
  2196.        
  2197.         [System.Diagnostics.Conditional("_LOGGING")]
  2198.         public static void DebugOutChnl(string s)
  2199.         {
  2200.             // BCLDebug.Trace("REMOTINGCHANNELS", "CHNL:" + s + "\n");
  2201.             Message.OutToUnmanagedDebugger("CHNL:" + s + "\n");
  2202.             // Console.WriteLine("CHNL:"+s+"\n");
  2203.         }
  2204.        
  2205.        
  2206.         [System.Diagnostics.Conditional("_LOGGING")]
  2207.         public static void RemotingTrace(params object[] messages)
  2208.         {
  2209.             BCLDebug.Trace("REMOTINGCHANNELS", messages);
  2210.         }
  2211.        
  2212.        
  2213.         [System.Diagnostics.Conditional("_DEBUG")]
  2214.         public static void RemotingAssert(bool condition, string message)
  2215.         {
  2216.             BCLDebug.Assert(condition, message);
  2217.         }
  2218.        
  2219.        
  2220.         [CLSCompliant(false)]
  2221.         public static void SetServerIdentity(MethodCall m, object srvID)
  2222.         {
  2223.             IInternalMessage im = (IInternalMessage)m;
  2224.             im.ServerIdentityObject = (ServerIdentity)srvID;
  2225.         }
  2226.        
  2227.        
  2228.        
  2229.         // access attribute cached on the reflection object
  2230.         static internal RemotingMethodCachedData GetReflectionCachedData(MethodBase mi)
  2231.         {
  2232.             RemotingMethodCachedData cache = null;
  2233.             cache = (RemotingMethodCachedData)mi.Cache[CacheObjType.RemotingData];
  2234.             if (cache == null) {
  2235.                 cache = new RemotingMethodCachedData(mi);
  2236.                 mi.Cache[CacheObjType.RemotingData] = cache;
  2237.             }
  2238.             return cache;
  2239.         }
  2240.         // GetCachedRemotingAttribute
  2241.         static internal RemotingTypeCachedData GetReflectionCachedData(Type mi)
  2242.         {
  2243.             RemotingTypeCachedData cache = null;
  2244.             cache = (RemotingTypeCachedData)mi.Cache[CacheObjType.RemotingData];
  2245.             if (cache == null) {
  2246.                 cache = new RemotingTypeCachedData(mi);
  2247.                 mi.Cache[CacheObjType.RemotingData] = cache;
  2248.             }
  2249.             return cache;
  2250.         }
  2251.         // GetCachedRemotingAttribute
  2252.         static internal RemotingCachedData GetReflectionCachedData(MemberInfo mi)
  2253.         {
  2254.             RemotingCachedData cache = null;
  2255.             cache = (RemotingCachedData)mi.Cache[CacheObjType.RemotingData];
  2256.             if (cache == null) {
  2257.                 if (mi is MethodBase)
  2258.                     cache = new RemotingMethodCachedData(mi);
  2259.                 else if (mi is Type)
  2260.                     cache = new RemotingTypeCachedData(mi);
  2261.                 else
  2262.                     cache = new RemotingCachedData(mi);
  2263.                
  2264.                 mi.Cache[CacheObjType.RemotingData] = cache;
  2265.             }
  2266.             return cache;
  2267.         }
  2268.         // GetCachedRemotingAttribute
  2269.         static internal RemotingCachedData GetReflectionCachedData(ParameterInfo reflectionObject)
  2270.         {
  2271.             RemotingCachedData cache = null;
  2272.             cache = (RemotingCachedData)reflectionObject.Cache[CacheObjType.RemotingData];
  2273.             if (cache == null) {
  2274.                 cache = new RemotingCachedData(reflectionObject);
  2275.                 reflectionObject.Cache[CacheObjType.RemotingData] = cache;
  2276.             }
  2277.            
  2278.             return cache;
  2279.         }
  2280.         // GetCachedRemotingAttribute
  2281.        
  2282.         public static SoapAttribute GetCachedSoapAttribute(object reflectionObject)
  2283.         {
  2284.             MemberInfo mi = reflectionObject as MemberInfo;
  2285.             if (mi != null)
  2286.                 return GetReflectionCachedData(mi).GetSoapAttribute();
  2287.             else
  2288.                 return GetReflectionCachedData((ParameterInfo)reflectionObject).GetSoapAttribute();
  2289.         }
  2290.         // GetCachedSoapAttribute
  2291.        
  2292.     }
  2293.     // InternalRemotingServices
  2294. }

Developer Fusion