2006-07-15 Jonathan Chambers <joncham@gmail.com>
[mono.git] / mcs / class / corlib / System.Runtime.Remoting / RemotingServices.cs
index 13dab7f79acb24eb6db4d743792928609618d9f4..9fa45c85328fe4eb1c1201bc9b481fd2b0faf7d1 100644 (file)
@@ -7,10 +7,7 @@
 //   Patrik Torstensson
 //
 // (C) 2001 Ximian, Inc.  http://www.ximian.com
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2006 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -32,7 +29,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.Diagnostics;
 using System.Text;
 using System.Reflection;
@@ -48,6 +44,8 @@ using System.Runtime.CompilerServices;
 using System.Runtime.Serialization;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.IO;
+using System.Runtime.Remoting.Services;
+using System.Security.Permissions;
 
 #if NET_2_0
 using System.Runtime.ConstrainedExecution;
@@ -104,7 +102,12 @@ namespace System.Runtime.Remoting
                        ReturnMessage result;
                        
                        Type tt = target.GetType ();
-                       MethodBase method = reqMsg.MethodBase.DeclaringType == tt ? reqMsg.MethodBase : tt.GetMethod(reqMsg.MethodName, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, (Type[]) reqMsg.MethodSignature, null);
+                       MethodBase method;
+                       if (reqMsg.MethodBase.DeclaringType == tt /*|| reqMsg.MethodBase.DeclaringType.IsInterface*/)
+                               method = reqMsg.MethodBase;
+                       else
+                               method = tt.GetMethod (reqMsg.MethodName, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, (Type[]) reqMsg.MethodSignature, null);
+                               
                        object oldContext = CallContext.SetCurrentCallContext (reqMsg.LogicalCallContext);
                        
                        try 
@@ -195,6 +198,7 @@ namespace System.Runtime.Remoting
                        {
                                LifetimeServices.StopTrackingLifetime (identity);
                                DisposeIdentity (identity);
+                               TrackingServices.NotifyDisconnectedObject (obj);
                                return true;
                        }
                }
@@ -224,18 +228,27 @@ namespace System.Runtime.Remoting
                        Type classToProxy = fRefine ? objref.ServerType : typeof (MarshalByRefObject);
                        if (classToProxy == null) classToProxy = typeof (MarshalByRefObject);
 
-                       if (objref.IsReferenceToWellKnow)
-                               return GetRemoteObject(objref, classToProxy);
+                       if (objref.IsReferenceToWellKnow) {
+                               object obj = GetRemoteObject(objref, classToProxy);
+                               TrackingServices.NotifyUnmarshaledObject (obj, objref);
+                               return obj;
+                       }
                        else
                        {
-                               if (classToProxy.IsContextful)
-                               {
+                               object obj;
+                               
+                               if (classToProxy.IsContextful) {
                                        // Look for a ProxyAttribute
                                        ProxyAttribute att = (ProxyAttribute) Attribute.GetCustomAttribute (classToProxy, typeof(ProxyAttribute),true);
-                                       if (att != null)
-                                               return att.CreateProxy (objref, classToProxy, null, null).GetTransparentProxy();
+                                       if (att != null) {
+                                               obj = att.CreateProxy (objref, classToProxy, null, null).GetTransparentProxy();
+                                               TrackingServices.NotifyUnmarshaledObject (obj, objref);
+                                               return obj;
+                                       }
                                }
-                               return GetProxyForRemoteObject (objref, classToProxy);
+                               obj = GetProxyForRemoteObject (objref, classToProxy);
+                               TrackingServices.NotifyUnmarshaledObject (obj, objref);
+                               return obj;
                        }
                }
 
@@ -271,7 +284,9 @@ namespace System.Runtime.Remoting
                                        else if (uri != null)
                                                throw new RemotingException ("It is not possible marshal a proxy of a remote object.");
 
-                                       return proxy.ObjectIdentity.CreateObjRef(requested_type);
+                                       ObjRef or = proxy.ObjectIdentity.CreateObjRef(requested_type);
+                                       TrackingServices.NotifyMarshaledObject (obj, or);
+                                       return or;
                                }
                        }
 
@@ -292,10 +307,15 @@ namespace System.Runtime.Remoting
                                        CreateClientActivatedServerIdentity (obj, requested_type, uri);
                        }
 
+                       ObjRef oref;
+                       
                        if (IsTransparentProxy (obj))
-                               return RemotingServices.GetRealProxy(obj).ObjectIdentity.CreateObjRef (requested_type);
+                               oref = RemotingServices.GetRealProxy(obj).ObjectIdentity.CreateObjRef (requested_type);
                        else
-                               return obj.CreateObjRef(requested_type);
+                               oref = obj.CreateObjRef(requested_type);
+                       
+                       TrackingServices.NotifyMarshaledObject (obj, oref);
+                       return oref;
                }
 
                static string NewUri ()
@@ -414,15 +434,25 @@ namespace System.Runtime.Remoting
 
                public static bool IsObjectOutOfAppDomain(object tp)
                {
+                       MarshalByRefObject mbr = tp as MarshalByRefObject;
+
+                       if (mbr == null)
+                               return false;
+
                        // TODO: use internal call for better performance
-                       Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
+                       Identity ident = GetObjectIdentity (mbr);
                        return ident is ClientIdentity;
                }
 
                public static bool IsObjectOutOfContext(object tp)
                {
+                       MarshalByRefObject mbr = tp as MarshalByRefObject;
+
+                       if (mbr == null)
+                               return false;
+
                        // TODO: use internal call for better performance
-                       Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
+                       Identity ident = GetObjectIdentity (mbr);
                        if (ident == null) return false;
                        
                        ServerIdentity sident = ident as ServerIdentity;
@@ -499,15 +529,48 @@ namespace System.Runtime.Remoting
                        RemotingProxy proxy = new RemotingProxy (type, ChannelServices.CrossContextUrl, activationAttributes);
                        return proxy.GetTransparentProxy();
                }
+
+               internal static object CreateClientProxyForComInterop (Type type)
+               {
+                       Mono.Interop.ComInteropProxy proxy = new Mono.Interop.ComInteropProxy (type);
+                       return proxy.GetTransparentProxy ();
+               }
        
                internal static Identity GetIdentityForUri (string uri)
                {
+                       string normUri = GetNormalizedUri (uri);
                        lock (uri_hash)
                        {
-                               return (Identity)uri_hash [GetNormalizedUri(uri)];
+                               Identity i = (Identity) uri_hash [normUri];
+
+                               if (i == null) {
+                                       normUri = RemoveAppNameFromUri (uri);
+                                       if (normUri != null)
+                                               i = (Identity) uri_hash [normUri];
+                               }
+
+                               return i;
                        }
                }
 
+               //
+               // If the specified uri starts with the application name,
+               // RemoveAppNameFromUri returns the uri w/out the leading
+               // application name, otherwise it returns null.
+               //
+               // Assumes that the uri is not normalized.
+               //
+               static string RemoveAppNameFromUri (string uri)
+               {
+                       string name = RemotingConfiguration.ApplicationName;
+                       if (name == null) return null;
+                       name = "/" + name + "/";
+                       if (uri.StartsWith (name))
+                               return uri.Substring (name.Length);
+                       else
+                               return null;
+               }
+
                internal static Identity GetObjectIdentity (MarshalByRefObject obj)
                {
                        if (IsTransparentProxy(obj))
@@ -654,6 +717,7 @@ namespace System.Runtime.Remoting
                }
 
                // This method is called by the runtime
+               [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)] // FIXME: to be reviewed
                internal static byte[] SerializeCallData (object obj)
                {
                        LogicalCallContext ctx = CallContext.CreateLogicalCallContext (false);
@@ -671,6 +735,7 @@ namespace System.Runtime.Remoting
                }
 
                // This method is called by the runtime
+               [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)] // FIXME: to be reviewed
                internal static object DeserializeCallData (byte[] array)
                {
                        if (array == null) return null;
@@ -687,6 +752,7 @@ namespace System.Runtime.Remoting
                }
                
                // This method is called by the runtime
+               [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)] // FIXME: to be reviewed
                internal static byte[] SerializeExceptionData (Exception ex)
                {
                        try {