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

  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:    ObjRef.cs
  18. **
  19. **
  20. ** Purpose: Defines the marshaled object reference class and related
  21. **          classes
  22. **
  23. **
  24. **
  25. ===========================================================*/
  26. namespace System.Runtime.Remoting
  27. {
  28.    
  29.     using System;
  30.     using System.Threading;
  31.     using System.Runtime.InteropServices;
  32.     using System.Runtime.Remoting;
  33.     using System.Runtime.Remoting.Channels;
  34.     using System.Runtime.Remoting.Contexts;
  35.     using System.Runtime.Remoting.Messaging;
  36.     using System.Runtime.Remoting.Metadata;
  37.     using System.Runtime.Serialization;
  38.     using System.Reflection;
  39.     using System.Security.Permissions;
  40.     using Win32Native = Microsoft.Win32.Win32Native;
  41.     using System.Runtime.ConstrainedExecution;
  42.     using System.Globalization;
  43.    
  44.    
  45.    
  46.     //** Purpose: Interface for providing type information. Users can use this
  47.     //** interface to provide custom type information which is carried
  48.     //** along with the ObjRef.
  49.     [System.Runtime.InteropServices.ComVisible(true)]
  50.     public interface IRemotingTypeInfo
  51.     {
  52.         // Return the fully qualified type name
  53.         string TypeName {
  54.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  55.             get;
  56.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  57.             set;
  58.         }
  59.        
  60.         // Check whether the given type can be cast to the type this
  61.         // interface represents
  62.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  63.         bool CanCastTo(Type fromType, object o);
  64.     }
  65.    
  66.     //** Purpose: Interface for providing channel information. Users can use this
  67.     //** interface to provide custom channel information which is carried
  68.     //** along with the ObjRef.
  69.     [System.Runtime.InteropServices.ComVisible(true)]
  70.     public interface IChannelInfo
  71.     {
  72.         // Get/Set the channel data for each channel
  73.         object[] ChannelData {
  74.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  75.             get;
  76.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  77.             set;
  78.         }
  79.     }
  80.    
  81.     //** Purpose: Interface for providing envoy information. Users can use this
  82.     //** interface to provide custom envoy information which is carried
  83.     //** along with the ObjRef.
  84.     [System.Runtime.InteropServices.ComVisible(true)]
  85.     public interface IEnvoyInfo
  86.     {
  87.         // Get/Set the envoy sinks
  88.         IMessageSink EnvoySinks {
  89.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  90.             get;
  91.             [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  92.             set;
  93.         }
  94.     }
  95.    
  96.    
  97.    
  98.     [Serializable()]
  99.     internal class TypeInfo : IRemotingTypeInfo
  100.     {
  101.         private string serverType;
  102.         private string[] serverHierarchy;
  103.         private string[] interfacesImplemented;
  104.        
  105.         // Return the fully qualified type name
  106.         public virtual string TypeName {
  107.             get { return serverType; }
  108.             set { serverType = value; }
  109.         }
  110.        
  111.         // Check whether the given type can be cast to the type this
  112.         // interface represents
  113.         public virtual bool CanCastTo(Type castType, object o)
  114.         {
  115.             if (null != castType) {
  116.                 // check for System.Object and MBRO since those aren't included in the
  117.                 // heirarchy
  118.                 if ((castType == typeof(MarshalByRefObject)) || (castType == typeof(object))) {
  119.                     return true;
  120.                 }
  121.                 else if (castType.IsInterface) {
  122.                     if (interfacesImplemented != null)
  123.                         return CanCastTo(castType, InterfacesImplemented);
  124.                     else
  125.                         return false;
  126.                 }
  127.                 else if (castType.IsMarshalByRef) {
  128.                     if (CompareTypes(castType, serverType))
  129.                         return true;
  130.                    
  131.                     if ((serverHierarchy != null) && CanCastTo(castType, ServerHierarchy))
  132.                         return true;
  133.                 }
  134.             }
  135.            
  136.             return false;
  137.         }
  138.        
  139.         static internal string GetQualifiedTypeName(Type type)
  140.         {
  141.             if (type == null)
  142.                 return null;
  143.            
  144.             return RemotingServices.GetDefaultQualifiedTypeName(type);
  145.         }
  146.        
  147.         static internal bool ParseTypeAndAssembly(string typeAndAssembly, out string typeName, out string assemName)
  148.         {
  149.             if (typeAndAssembly == null) {
  150.                 typeName = null;
  151.                 assemName = null;
  152.                 return false;
  153.             }
  154.            
  155.             int index = typeAndAssembly.IndexOf(',');
  156.             if (index == -1) {
  157.                 typeName = typeAndAssembly;
  158.                 assemName = null;
  159.                 return true;
  160.             }
  161.            
  162.             // type name is everything up to the first comma
  163.             typeName = typeAndAssembly.Substring(0, index);
  164.            
  165.             // assembly name is the rest
  166.             assemName = typeAndAssembly.Substring(index + 1).Trim();
  167.            
  168.             return true;
  169.         }
  170.         // ParseTypeAndAssembly
  171.        
  172.         internal TypeInfo(Type typeOfObj)
  173.         {
  174.             ServerType = GetQualifiedTypeName(typeOfObj);
  175.            
  176.             // Compute the length of the server hierarchy
  177.             Type currType = typeOfObj.BaseType;
  178.             // typeOfObj is the root of all classes, but not included in the hierarachy.
  179.             Message.DebugOut("RemotingServices::TypeInfo: Determining length of server heirarchy\n");
  180.             int hierarchyLen = 0;
  181.             while ((currType != typeof(MarshalByRefObject)) && (currType != null)) {
  182.                 currType = currType.BaseType;
  183.                 hierarchyLen++;
  184.             }
  185.            
  186.             // Allocate an array big enough to store the hierarchy
  187.             Message.DebugOut("RemotingServices::TypeInfo: Determined length of server heirarchy\n");
  188.             string[] serverHierarchy = null;
  189.             if (hierarchyLen > 0) {
  190.                 serverHierarchy = new string[hierarchyLen];
  191.                
  192.                 currType = typeOfObj.BaseType;
  193.                 for (int i = 0; i < hierarchyLen; i++) {
  194.                     serverHierarchy[i] = GetQualifiedTypeName(currType);
  195.                     currType = currType.BaseType;
  196.                 }
  197.             }
  198.            
  199.             this.ServerHierarchy = serverHierarchy;
  200.            
  201.             Message.DebugOut("RemotingServices::TypeInfo: Getting implemented interfaces\n");
  202.             // Set the interfaces implemented
  203.             Type[] interfaces = typeOfObj.GetInterfaces();
  204.             string[] interfaceNames = null;
  205.             // If the requested type itself is an interface we should add that to the
  206.             // interfaces list as well
  207.             bool isInterface = typeOfObj.IsInterface;
  208.             if (interfaces.Length > 0 || isInterface) {
  209.                 interfaceNames = new string[interfaces.Length + (isInterface ? 1 : 0)];
  210.                 for (int i = 0; i < interfaces.Length; i++) {
  211.                     interfaceNames[i] = GetQualifiedTypeName(interfaces[i]);
  212.                 }
  213.                 if (isInterface)
  214.                     interfaceNames[interfaceNames.Length - 1] = GetQualifiedTypeName(typeOfObj);
  215.             }
  216.            
  217.             this.InterfacesImplemented = interfaceNames;
  218.         }
  219.         // TypeInfo
  220.         internal string ServerType {
  221.             get { return serverType; }
  222.             set { serverType = value; }
  223.         }
  224.        
  225.         private string[] ServerHierarchy {
  226.             get { return serverHierarchy; }
  227.             set { serverHierarchy = value; }
  228.         }
  229.        
  230.         private string[] InterfacesImplemented {
  231.             get { return interfacesImplemented; }
  232.             set { interfacesImplemented = value; }
  233.         }
  234.        
  235.         private bool CompareTypes(Type type1, string type2)
  236.         {
  237.             Type type = RemotingServices.InternalGetTypeFromQualifiedTypeName(type2);
  238.            
  239.             return type1 == type;
  240.         }
  241.        
  242.         private bool CanCastTo(Type castType, string[] types)
  243.         {
  244.             bool fCastOK = false;
  245.            
  246.             // Run through the type names and see if there is a
  247.             // matching type
  248.            
  249.             if (null != castType) {
  250.                 for (int i = 0; i < types.Length; i++) {
  251.                     if (CompareTypes(castType, types[i])) {
  252.                         fCastOK = true;
  253.                         break;
  254.                     }
  255.                 }
  256.             }
  257.            
  258.             Message.DebugOut("CanCastTo returning " + fCastOK + " for type " + castType.FullName + "\n");
  259.             return fCastOK;
  260.         }
  261.     }
  262.    
  263.     [Serializable()]
  264.     internal class DynamicTypeInfo : TypeInfo
  265.     {
  266.         internal DynamicTypeInfo(Type typeOfObj) : base(typeOfObj)
  267.         {
  268.         }
  269.         public override bool CanCastTo(Type castType, object o)
  270.         {
  271.             return ((MarshalByRefObject)o).IsInstanceOfType(castType);
  272.         }
  273.     }
  274.    
  275.     [Serializable()]
  276.     internal sealed class ChannelInfo : IChannelInfo
  277.     {
  278.         private object[] channelData;
  279.        
  280.         internal ChannelInfo()
  281.         {
  282.             ChannelData = ChannelServices.CurrentChannelData;
  283.         }
  284.        
  285.         public object[] ChannelData {
  286.             get { return channelData; }
  287.             set { channelData = value; }
  288.         }
  289.        
  290.     }
  291.    
  292.     [Serializable()]
  293.     internal sealed class EnvoyInfo : IEnvoyInfo
  294.     {
  295.         private IMessageSink envoySinks;
  296.        
  297.         static internal IEnvoyInfo CreateEnvoyInfo(ServerIdentity serverID)
  298.         {
  299.             IEnvoyInfo info = null;
  300.             if (null != serverID) {
  301.                 // Set the envoy sink chain
  302.                 if (serverID.EnvoyChain == null) {
  303.                     serverID.RaceSetEnvoyChain(serverID.ServerContext.CreateEnvoyChain(serverID.TPOrObject));
  304.                 }
  305.                
  306.                 // Create an envoy info object only if necessary
  307.                 IMessageSink sink = serverID.EnvoyChain as EnvoyTerminatorSink;
  308.                 if (null == sink) {
  309.                     // The chain consists of more than a terminator sink
  310.                     // Go ahead and create an envoy info structure, otherwise
  311.                     // a null is returned and we recreate the terminator sink
  312.                     // on the other side, automatically.
  313.                     info = new EnvoyInfo(serverID.EnvoyChain);
  314.                 }
  315.             }
  316.            
  317.             return info;
  318.         }
  319.        
  320.         private EnvoyInfo(IMessageSink sinks)
  321.         {
  322.             BCLDebug.Assert(null != sinks, "null != sinks");
  323.             EnvoySinks = sinks;
  324.         }
  325.        
  326.         public IMessageSink EnvoySinks {
  327.             get { return envoySinks; }
  328.             set { envoySinks = value; }
  329.         }
  330.     }
  331.    
  332.     [Serializable()]
  333.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  334.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  335.     [System.Runtime.InteropServices.ComVisible(true)]
  336.     public class ObjRef : IObjectReference, ISerializable
  337.     {
  338.         // This flag is used to distinguish between the case where
  339.         // an actual object was marshaled as compared to the case
  340.         // where someone wants to pass the ObjRef itself to a remote call
  341.         internal const int FLG_MARSHALED_OBJECT = 1;
  342.        
  343.         // This flag is used to mark a wellknown objRef (i.e. result
  344.         // of marshaling a proxy that was obtained through a Connect call)
  345.         internal const int FLG_WELLKNOWN_OBJREF = 2;
  346.        
  347.         // This flag is used for a lightweight Object Reference. It is sent to those clients
  348.         // which are not interested in receiving a full-fledged ObjRef. An example
  349.         // of such a client will be a mobile device with hard memory and processing
  350.         // constraints.
  351.         // NOTE: In this case ALL the fields EXCEPT the uri/flags field are NULL.
  352.         internal const int FLG_LITE_OBJREF = 4;
  353.        
  354.         internal const int FLG_PROXY_ATTRIBUTE = 8;
  355.         //
  356.         //If you change the fields here, you must all change them in
  357.         //RemotingSurrogate::GetObjectData
  358.         //
  359.         internal string uri;
  360.         internal IRemotingTypeInfo typeInfo;
  361.         internal IEnvoyInfo envoyInfo;
  362.         internal IChannelInfo channelInfo;
  363.         internal int objrefFlags;
  364.         internal GCHandle srvIdentity;
  365.         internal int domainID;
  366.        
  367.         internal void SetServerIdentity(GCHandle hndSrvIdentity)
  368.         {
  369.             srvIdentity = hndSrvIdentity;
  370.         }
  371.        
  372.         internal GCHandle GetServerIdentity()
  373.         {
  374.             return srvIdentity;
  375.         }
  376.        
  377.         internal void SetDomainID(int id)
  378.         {
  379.             domainID = id;
  380.         }
  381.        
  382.         internal int GetDomainID()
  383.         {
  384.             return domainID;
  385.         }
  386.        
  387.         // Static fields
  388.         private static Type orType = typeof(ObjRef);
  389.        
  390.        
  391.         // shallow copy constructor used for smuggling.
  392.         private ObjRef(ObjRef o)
  393.         {
  394.             BCLDebug.Assert(o.GetType() == typeof(ObjRef), "this should be just an ObjRef");
  395.            
  396.             uri = o.uri;
  397.             typeInfo = o.typeInfo;
  398.             envoyInfo = o.envoyInfo;
  399.             channelInfo = o.channelInfo;
  400.             objrefFlags = o.objrefFlags;
  401.             SetServerIdentity(o.GetServerIdentity());
  402.             SetDomainID(o.GetDomainID());
  403.         }
  404.         // ObjRef
  405.         public ObjRef(MarshalByRefObject o, Type requestedType)
  406.         {
  407.             bool fServer;
  408.             Identity id = MarshalByRefObject.GetIdentity(o, out fServer);
  409.             Init(o, id, requestedType);
  410.         }
  411.        
  412.         protected ObjRef(SerializationInfo info, StreamingContext context)
  413.         {
  414.             string url = null;
  415.             // an objref lite url
  416.             bool bFoundFIsMarshalled = false;
  417.            
  418.             SerializationInfoEnumerator e = info.GetEnumerator();
  419.             while (e.MoveNext()) {
  420.                 if (e.Name.Equals("uri")) {
  421.                     uri = (string)e.Value;
  422.                 }
  423.                 else if (e.Name.Equals("typeInfo")) {
  424.                     typeInfo = (IRemotingTypeInfo)e.Value;
  425.                 }
  426.                 else if (e.Name.Equals("envoyInfo")) {
  427.                     envoyInfo = (IEnvoyInfo)e.Value;
  428.                 }
  429.                 else if (e.Name.Equals("channelInfo")) {
  430.                     channelInfo = (IChannelInfo)e.Value;
  431.                 }
  432.                 else if (e.Name.Equals("objrefFlags")) {
  433.                     object o = e.Value;
  434.                     if (o.GetType() == typeof(string)) {
  435.                         objrefFlags = ((IConvertible)o).ToInt32(null);
  436.                     }
  437.                     else {
  438.                         objrefFlags = (int)o;
  439.                     }
  440.                 }
  441.                 else if (e.Name.Equals("fIsMarshalled")) {
  442.                     int value;
  443.                     object o = e.Value;
  444.                     if (o.GetType() == typeof(string))
  445.                         value = ((IConvertible)o).ToInt32(null);
  446.                     else
  447.                         value = (int)o;
  448.                    
  449.                     if (value == 0)
  450.                         bFoundFIsMarshalled = true;
  451.                 }
  452.                 else if (e.Name.Equals("url")) {
  453.                     url = (string)e.Value;
  454.                 }
  455.                 else if (e.Name.Equals("SrvIdentity")) {
  456.                     SetServerIdentity((GCHandle)e.Value);
  457.                 }
  458.                 else if (e.Name.Equals("DomainId")) {
  459.                     SetDomainID((int)e.Value);
  460.                 }
  461.             }
  462.            
  463.             if (!bFoundFIsMarshalled) {
  464.                 // This ObjRef was not passed as a parameter, so we need to unmarshal it.
  465.                 objrefFlags |= FLG_MARSHALED_OBJECT;
  466.             }
  467.             else
  468.                 objrefFlags &= ~FLG_MARSHALED_OBJECT;
  469.            
  470.             // If only url is present, then it is an ObjRefLite.
  471.             if (url != null) {
  472.                 uri = url;
  473.                 objrefFlags |= FLG_LITE_OBJREF;
  474.             }
  475.            
  476.         }
  477.         // ObjRef .ctor
  478.        
  479.         internal bool CanSmuggle()
  480.         {
  481.             // make sure this isn't a derived class or an ObjRefLite
  482.             if ((this.GetType() != typeof(ObjRef)) || IsObjRefLite())
  483.                 return false;
  484.            
  485.             Type typeOfTypeInfo = null;
  486.             if (typeInfo != null)
  487.                 typeOfTypeInfo = typeInfo.GetType();
  488.            
  489.             Type typeOfChannelInfo = null;
  490.             if (channelInfo != null)
  491.                 typeOfChannelInfo = channelInfo.GetType();
  492.            
  493.             if (((typeOfTypeInfo == null) || (typeOfTypeInfo == typeof(TypeInfo)) || (typeOfTypeInfo == typeof(DynamicTypeInfo))) && (envoyInfo == null) && ((typeOfChannelInfo == null) || (typeOfChannelInfo == typeof(ChannelInfo)))) {
  494.                 if (channelInfo != null) {
  495.                     foreach (object channelData in channelInfo.ChannelData) {
  496.                         if (!(channelData is CrossAppDomainData)) {
  497.                             return false;
  498.                         }
  499.                     }
  500.                 }
  501.                
  502.                 return true;
  503.             }
  504.             else {
  505.                 return false;
  506.             }
  507.         }
  508.         // CanSmuggle
  509.         internal ObjRef CreateSmuggleableCopy()
  510.         {
  511.             BCLDebug.Assert(CanSmuggle(), "Caller should have made sure that CanSmuggle() was true first.");
  512.            
  513.             return new ObjRef(this);
  514.         }
  515.         // CreateSmuggleableCopy
  516.        
  517.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  518.         public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
  519.         {
  520.             if (info == null) {
  521.                 throw new ArgumentNullException("info");
  522.             }
  523.            
  524.             info.SetType(orType);
  525.            
  526.             if (!IsObjRefLite()) {
  527.                 info.AddValue("uri", uri, typeof(string));
  528.                 info.AddValue("objrefFlags", (int)objrefFlags);
  529.                 info.AddValue("typeInfo", typeInfo, typeof(IRemotingTypeInfo));
  530.                 info.AddValue("envoyInfo", envoyInfo, typeof(IEnvoyInfo));
  531.                 info.AddValue("channelInfo", GetChannelInfoHelper(), typeof(IChannelInfo));
  532.             }
  533.             else {
  534.                 info.AddValue("url", uri, typeof(string));
  535.             }
  536.         }
  537.         // GetObjectDataHelper
  538.        
  539.         // This method retrieves the channel info object to be serialized.
  540.         // It does special checking to see if a channel url needs to be bashed
  541.         // (currently used for switching "http://..." url to "https://...".
  542.         private IChannelInfo GetChannelInfoHelper()
  543.         {
  544.             ChannelInfo oldChannelInfo = channelInfo as ChannelInfo;
  545.             if (oldChannelInfo == null)
  546.                 return channelInfo;
  547.            
  548.             object[] oldChannelData = oldChannelInfo.ChannelData;
  549.             if (oldChannelData == null)
  550.                 return oldChannelInfo;
  551.            
  552.             string[] bashInfo = (string[])CallContext.GetData("__bashChannelUrl");
  553.             if (bashInfo == null)
  554.                 return oldChannelInfo;
  555.            
  556.             string urlToBash = bashInfo[0];
  557.             string replacementUrl = bashInfo[1];
  558.            
  559.             ChannelInfo newChInfo = new ChannelInfo();
  560.             newChInfo.ChannelData = new object[oldChannelData.Length];
  561.             for (int co = 0; co < oldChannelData.Length; co++) {
  562.                 newChInfo.ChannelData[co] = oldChannelData[co];
  563.                
  564.                 ChannelDataStore channelDataStore = newChInfo.ChannelData[co] as ChannelDataStore;
  565.                 if (channelDataStore != null) {
  566.                     string[] urls = channelDataStore.ChannelUris;
  567.                     if ((urls != null) && (urls.Length == 1) && urls[0].Equals(urlToBash)) {
  568.                         ChannelDataStore newChannelDataStore = channelDataStore.InternalShallowCopy();
  569.                         newChannelDataStore.ChannelUris = new string[1];
  570.                         newChannelDataStore.ChannelUris[0] = replacementUrl;
  571.                        
  572.                         newChInfo.ChannelData[co] = newChannelDataStore;
  573.                     }
  574.                 }
  575.             }
  576.            
  577.             return newChInfo;
  578.         }
  579.         // GetChannelInfoHelper
  580.        
  581.        
  582.         // Note: The uri will be either objURI (for normal marshals) or
  583.         // it will be the URL if a wellknown object's proxy is marshaled
  584.         // Basically we will take whatever the URI getter on Identity gives us
  585.        
  586.         public virtual string URI {
  587.             get { return uri; }
  588.             set { uri = value; }
  589.         }
  590.        
  591.         public virtual IRemotingTypeInfo TypeInfo {
  592.             get { return typeInfo; }
  593.             set { typeInfo = value; }
  594.         }
  595.        
  596.         public virtual IEnvoyInfo EnvoyInfo {
  597.             get { return envoyInfo; }
  598.             set { envoyInfo = value; }
  599.         }
  600.        
  601.         public virtual IChannelInfo ChannelInfo {
  602.             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  603.             get { return channelInfo; }
  604.             set { channelInfo = value; }
  605.         }
  606.        
  607.        
  608.         // This is called when doing fix-ups during deserialization
  609.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  610.         public virtual object GetRealObject(StreamingContext context)
  611.         {
  612.             return GetRealObjectHelper();
  613.         }
  614.         // This is the common helper called by serialization / smuggling
  615.        
  616.         internal object GetRealObjectHelper()
  617.         {
  618.             // Check if we are a result of serialiazing an MBR object
  619.             // or if someone wanted to pass an ObjRef itself
  620.             if (!IsMarshaledObject()) {
  621.                 BCLDebug.Trace("REMOTE", "ObjRef.GetRealObject: Returning *this*\n");
  622.                 return this;
  623.             }
  624.             else {
  625.                 // Check if this is a lightweight objref
  626.                 if (IsObjRefLite()) {
  627.                     BCLDebug.Assert(null != uri, "null != uri");
  628.                    
  629.                     // transform the url, if this is a local object (we know it is local
  630.                     // if we find the current application id in the url)
  631.                     int index = uri.IndexOf(RemotingConfiguration.ApplicationId);
  632.                    
  633.                     // we need to be past 0, since we have to back up a space and pick up
  634.                     // a slash.
  635.                     if (index > 0)
  636.                         uri = uri.Substring(index - 1);
  637.                 }
  638.                
  639.                 // In the general case, 'this' is the
  640.                 // objref of an activated object
  641.                
  642.                 // It may also be a well known object ref ... which came by
  643.                 // because someone did a Connect(URL) and then passed the proxy
  644.                 // over to a remote method call.
  645.                
  646.                 // The below call handles both cases.
  647.                 bool fRefine = !(GetType() == typeof(ObjRef));
  648.                 object ret = RemotingServices.Unmarshal(this, fRefine);
  649.                
  650.                 // Check for COMObject & do some special custom marshaling
  651.                 ret = GetCustomMarshaledCOMObject(ret);
  652.                
  653.                 return ret;
  654.             }
  655.            
  656.         }
  657.        
  658.         private object GetCustomMarshaledCOMObject(object ret)
  659.         {
  660.             return ret;
  661.         }
  662.        
  663.         public ObjRef()
  664.         {
  665.             objrefFlags = 0;
  666.         }
  667.        
  668.         internal bool IsMarshaledObject()
  669.         {
  670.             return (objrefFlags & FLG_MARSHALED_OBJECT) == FLG_MARSHALED_OBJECT;
  671.         }
  672.        
  673.         internal void SetMarshaledObject()
  674.         {
  675.             objrefFlags |= FLG_MARSHALED_OBJECT;
  676.         }
  677.        
  678.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  679.         internal bool IsWellKnown()
  680.         {
  681.             return (objrefFlags & FLG_WELLKNOWN_OBJREF) == FLG_WELLKNOWN_OBJREF;
  682.         }
  683.        
  684.         internal void SetWellKnown()
  685.         {
  686.             objrefFlags |= FLG_WELLKNOWN_OBJREF;
  687.         }
  688.        
  689.         internal bool HasProxyAttribute()
  690.         {
  691.             return (objrefFlags & FLG_PROXY_ATTRIBUTE) == FLG_PROXY_ATTRIBUTE;
  692.         }
  693.        
  694.         internal void SetHasProxyAttribute()
  695.         {
  696.             objrefFlags |= FLG_PROXY_ATTRIBUTE;
  697.         }
  698.        
  699.         internal bool IsObjRefLite()
  700.         {
  701.             return (objrefFlags & FLG_LITE_OBJREF) == FLG_LITE_OBJREF;
  702.         }
  703.        
  704.         internal void SetObjRefLite()
  705.         {
  706.             objrefFlags |= FLG_LITE_OBJREF;
  707.         }
  708.        
  709.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  710.         private CrossAppDomainData GetAppDomainChannelData()
  711.         {
  712.             BCLDebug.Assert(ObjRef.IsWellFormed(this), "ObjRef.IsWellFormed()");
  713.            
  714.             // Look at the ChannelData part to find CrossAppDomainData
  715.             int i = 0;
  716.             CrossAppDomainData xadData = null;
  717.             while (i < ChannelInfo.ChannelData.Length) {
  718.                 xadData = ChannelInfo.ChannelData[i] as CrossAppDomainData;
  719.                 if (null != xadData) {
  720.                     return xadData;
  721.                 }
  722.                 i++;
  723.             }
  724.            
  725.             // AdData could be null for user-created objRefs.
  726.             return null;
  727.         }
  728.        
  729.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  730.         public bool IsFromThisProcess()
  731.         {
  732.             //Wellknown objects may or may not be in the same process
  733.             //Hence return false;
  734.             if (IsWellKnown())
  735.                 return false;
  736.            
  737.             CrossAppDomainData xadData = GetAppDomainChannelData();
  738.             if (xadData != null) {
  739.                 return xadData.IsFromThisProcess();
  740.             }
  741.             return false;
  742.         }
  743.        
  744.         public bool IsFromThisAppDomain()
  745.         {
  746.             CrossAppDomainData xadData = GetAppDomainChannelData();
  747.             if (xadData != null) {
  748.                 return xadData.IsFromThisAppDomain();
  749.             }
  750.             return false;
  751.         }
  752.        
  753.         // returns the internal context ID for the server context if
  754.         // it is from the same process && the appDomain of the server
  755.         // is still valid. If the objRef is from this process, the domain
  756.         // id found in the objref is always returned.
  757.        
  758.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  759.         internal Int32 GetServerDomainId()
  760.         {
  761.             if (!IsFromThisProcess())
  762.                 return 0;
  763.             CrossAppDomainData xadData = GetAppDomainChannelData();
  764.             BCLDebug.Assert(xadData != null, "bad objRef?");
  765.             return xadData.DomainID;
  766.            
  767.         }
  768.        
  769.         internal IntPtr GetServerContext(out int domainId)
  770.         {
  771.             IntPtr contextId = IntPtr.Zero;
  772.             domainId = 0;
  773.             if (IsFromThisProcess()) {
  774.                 CrossAppDomainData xadData = GetAppDomainChannelData();
  775.                 BCLDebug.Assert(xadData != null, "bad objRef?");
  776.                 domainId = xadData.DomainID;
  777.                 if (AppDomain.IsDomainIdValid(xadData.DomainID)) {
  778.                     contextId = xadData.ContextID;
  779.                 }
  780.             }
  781.             return contextId;
  782.         }
  783.        
  784.         //
  785.         //
  786.         internal void Init(object o, Identity idObj, Type requestedType)
  787.         {
  788.             Message.DebugOut("RemotingServices::FillObjRef: IN");
  789.             BCLDebug.Assert(idObj != null, "idObj != null");
  790.            
  791.             // Set the URI of the object to be marshaled
  792.             uri = idObj.URI;
  793.            
  794.             // Figure out the type
  795.             MarshalByRefObject obj = idObj.TPOrObject;
  796.             BCLDebug.Assert(null != obj, "Identity not setup correctly");
  797.            
  798.             // Get the type of the object
  799.             Type serverType = null;
  800.             if (!RemotingServices.IsTransparentProxy(obj)) {
  801.                 serverType = obj.GetType();
  802.             }
  803.             else {
  804.                 serverType = RemotingServices.GetRealProxy(obj).GetProxiedType();
  805.             }
  806.            
  807.             Type typeOfObj = (null == requestedType ? serverType : requestedType);
  808.            
  809.             // Make sure that the server and requested types are compatible
  810.             // (except for objects that implement IMessageSink, since we
  811.             // just hand off the message instead of invoking the proxy)
  812.             if ((null != requestedType) && !requestedType.IsAssignableFrom(serverType) && (!typeof(IMessageSink).IsAssignableFrom(serverType))) {
  813.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_InvalidRequestedType"), requestedType.ToString()));
  814.                 ;
  815.             }
  816.            
  817.             {
  818.                 RemotingTypeCachedData cache = (RemotingTypeCachedData)InternalRemotingServices.GetReflectionCachedData(typeOfObj);
  819.                
  820.                 TypeInfo = (IRemotingTypeInfo)cache.TypeInfo;
  821.             }
  822.            
  823.             if (!idObj.IsWellKnown()) {
  824.                 // Create the envoy info
  825.                 EnvoyInfo = System.Runtime.Remoting.EnvoyInfo.CreateEnvoyInfo(idObj as ServerIdentity);
  826.                
  827.                 // Create the channel info
  828.                 IChannelInfo chan = (IChannelInfo)new ChannelInfo();
  829.                 // Make sure the channelInfo only has x-appdomain data since the objref is agile while other
  830.                 // channelData might not be and regardless this data is useless for an appdomain proxy
  831.                 if (o is AppDomain) {
  832.                     object[] channelData = chan.ChannelData;
  833.                     int channelDataLength = channelData.Length;
  834.                     object[] newChannelData = new object[channelDataLength];
  835.                     Array.Copy(channelData, newChannelData, channelDataLength);
  836.                     for (int i = 0; i < channelDataLength; i++) {
  837.                         if (!(newChannelData[i] is CrossAppDomainData))
  838.                             newChannelData[i] = null;
  839.                     }
  840.                     chan.ChannelData = newChannelData;
  841.                 }
  842.                 ChannelInfo = chan;
  843.                
  844.                 if (serverType.HasProxyAttribute) {
  845.                     SetHasProxyAttribute();
  846.                 }
  847.             }
  848.             else {
  849.                 SetWellKnown();
  850.             }
  851.            
  852.             // See if we should and can use a url obj ref?
  853.             if (ShouldUseUrlObjRef()) {
  854.                 if (IsWellKnown()) {
  855.                     // full uri already supplied.
  856.                     SetObjRefLite();
  857.                 }
  858.                 else {
  859.                     string httpUri = ChannelServices.FindFirstHttpUrlForObject(URI);
  860.                     if (httpUri != null) {
  861.                         URI = httpUri;
  862.                         SetObjRefLite();
  863.                     }
  864.                 }
  865.             }
  866.         }
  867.         // Init
  868.        
  869.         // determines if a particular type should use a url obj ref
  870.         static internal bool ShouldUseUrlObjRef()
  871.         {
  872.             return RemotingConfigHandler.UrlObjRefMode;
  873.         }
  874.         // ShouldUseUrlObjRef
  875.        
  876.         // Check whether the objref is well formed
  877.         static internal bool IsWellFormed(ObjRef objectRef)
  878.         {
  879.             // We skip the wellformed check for wellKnown,
  880.             // objref-lite and custom objrefs
  881.             bool wellFormed = true;
  882.             if ((null == objectRef) || (null == objectRef.URI) || (!(objectRef.IsWellKnown() || objectRef.IsObjRefLite() || objectRef.GetType() != orType) && (null == objectRef.ChannelInfo))) {
  883.                 wellFormed = false;
  884.             }
  885.            
  886.             return wellFormed;
  887.         }
  888.     }
  889.     // ObjRef
  890.    
  891. }

Developer Fusion