In Mono.Interop:
authorRobert Jordan <robertj@gmx.net>
Sat, 18 Jul 2009 23:15:10 +0000 (23:15 -0000)
committerRobert Jordan <robertj@gmx.net>
Sat, 18 Jul 2009 23:15:10 +0000 (23:15 -0000)
2009-07-11  Robert Jordan  <robertj@gmx.net>

* ComInteropProxy.cs: Implement CreateProxy. Hide public/internal
ctors forcing CreateProxy's usage. Hide CacheProxy since the
runtime is able to lookup it anyways.
Fixes bug #520437.

In System:
2009-07-19  Robert Jordan  <robertj@gmx.net>

* __ComObject.cs: Factor out Initialize method and expose it to
ComInteropProxy. Fixes bug #520437.

In System.Runtime.Remoting:
2009-07-11  Robert Jordan  <robertj@gmx.net>

* RemotingServices.cs: Track ComInteropProxy's changes.

svn path=/trunk/mcs/; revision=138182

mcs/class/corlib/Mono.Interop/ChangeLog
mcs/class/corlib/Mono.Interop/ComInteropProxy.cs
mcs/class/corlib/System.Runtime.Remoting/ChangeLog
mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/__ComObject.cs

index c543f43282065d49b3b731f90857283391ab1ad2..06f4a46e67b8b9594b5848549405b1b8dcb724e7 100644 (file)
@@ -1,3 +1,10 @@
+2009-07-11  Robert Jordan  <robertj@gmx.net>
+
+       * ComInteropProxy.cs: Implement CreateProxy. Hide public/internal
+       ctors forcing CreateProxy's usage. Hide CacheProxy since the
+       runtime is able to lookup it anyways.
+       Fixes bug #520437.
+
 2007-07-26  Jonathan Chambers  <joncham@gmail.com>
 
        * ComInteropProxy.cs: Call Marshal.Release after Marshal.QI
index a7c8f8f6febcc0ae282fc9e4292d6fa55f7e233f..865e448ee48015e66cb3cee78cb03f9fc2c49469 100644 (file)
@@ -54,7 +54,8 @@ namespace Mono.Interop
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal extern static ComInteropProxy FindProxy (IntPtr pItf);
 
-               public ComInteropProxy (Type t)
+               // Private. Objects must be created with CreateProxy.
+               ComInteropProxy (Type t)
                        : base (t)
                {
                        // object only created here
@@ -62,16 +63,16 @@ namespace Mono.Interop
                        com_object = __ComObject.CreateRCW (t);
                }
 
-               internal void CacheProxy ()
+               void CacheProxy ()
                {
                        // called from unmanaged code after .ctor is invoked
                        // we need .ctor to create unmanaged object and thus IUnknown property value
                        AddProxy (com_object.IUnknown, this);
                }
 
-        internal ComInteropProxy (IntPtr pUnk)
-            : this (pUnk, typeof (__ComObject))
-        {
+               ComInteropProxy (IntPtr pUnk)
+                       : this (pUnk, typeof (__ComObject))
+               {
                }
 
                internal ComInteropProxy (IntPtr pUnk, Type t)
@@ -99,6 +100,25 @@ namespace Mono.Interop
                        }
                }
 
+               // Gets the proxy of the specified COM type. If the COM type is
+               // already known, a cached proxy will be returned.
+               internal static ComInteropProxy CreateProxy (Type t)
+               {
+                       ComInteropProxy proxy = new ComInteropProxy (t);
+                       proxy.com_object.Initialize (t);
+
+                       ComInteropProxy cachedProxy = FindProxy (proxy.com_object.IUnknown);
+                       if (cachedProxy != null) {
+                               // check that the COM type of the cached proxy matches
+                               // the requested type. See 2nd part of bug #520437.
+                               Type cachedType = cachedProxy.com_object.GetType ();
+                               if (cachedType != t)
+                                       throw new InvalidCastException (String.Format ("Unable to cast object of type '{0}' to type '{1}'.", cachedType, t));
+                               return cachedProxy;
+                       }
+                       return proxy;
+               }
+
                public override IMessage Invoke (IMessage msg)
                {
                        Console.WriteLine ("Invoke");
index b830c7d62ae7f77a05c3397d28a9fdd2789cac7f..a6247c7e4e1acf1ebce78fdd90e03233a5a0b28e 100644 (file)
@@ -1,3 +1,7 @@
+2009-07-11  Robert Jordan  <robertj@gmx.net>
+
+       * RemotingServices.cs: Track ComInteropProxy's changes.
+
 2009-04-18  Mark Probst  <mark.probst@gmail.com>
 
        * RemotingServices.cs (GetDomainProxy): Make a copy of the array
index 257e0aeb1ec87b7115a1552b020556035c03b755..bbf3ef856ecc1bd11285c0ff3a4d1c472f5b8ad5 100644 (file)
@@ -581,7 +581,7 @@ namespace System.Runtime.Remoting
 
                internal static object CreateClientProxyForComInterop (Type type)
                {
-                       Mono.Interop.ComInteropProxy proxy = new Mono.Interop.ComInteropProxy (type);
+                       Mono.Interop.ComInteropProxy proxy = Mono.Interop.ComInteropProxy.CreateProxy (type);
                        return proxy.GetTransparentProxy ();
                }
        
index 446d59cb15863164e8f7af3b605778b24f09f41c..3a1cb44c0c976ac14c9b31f3b782732cfb40acb0 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-19  Robert Jordan  <robertj@gmx.net>
+
+       * __ComObject.cs: Factor out Initialize method and expose it to
+       ComInteropProxy. Fixes bug #520437.
+
 2009-07-14  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * Attribute.cs (GetCustomAttributes): Pass typeof(Attribute)
index 46a23abf9c35a37d4d25ffc8fee75a8081309a2f..803f535f93a03fd8535a0b7f574c817db3053377 100644 (file)
@@ -72,19 +72,26 @@ namespace System
 
                public __ComObject ()
                {
-                       Type t = GetType ();
-                       ObjectCreationDelegate ocd = ExtensibleClassFactory.GetObjectCreationCallback (t);
-                       if (ocd != null) {
-                               iunknown = ocd (IntPtr.Zero);
-                               if (iunknown == IntPtr.Zero)
-                                       throw new COMException (string.Format("ObjectCreationDelegate for type {0} failed to return a valid COM object", t));
-                       } else {
-                               int hr = CoCreateInstance (GetCLSID (t), IntPtr.Zero, 0x1 | 0x4 | 0x10, IID_IUnknown, out iunknown);
-                               Marshal.ThrowExceptionForHR (hr);
-                       }
+                       Initialize (GetType ());
                }
 
                internal __ComObject (Type t) {
+                       Initialize (t);
+               }
+
+               internal __ComObject (IntPtr pItf)
+               {
+                       Guid iid = IID_IUnknown;
+                       int hr = Marshal.QueryInterface (pItf, ref iid, out iunknown);
+                       Marshal.ThrowExceptionForHR (hr);
+               }
+
+               internal void Initialize (Type t)
+               {
+                       // Guard multiple invocation.
+                       if (iunknown != IntPtr.Zero)
+                               return;
+                       
                        ObjectCreationDelegate ocd = ExtensibleClassFactory.GetObjectCreationCallback (t);
                        if (ocd != null) {
                                iunknown = ocd (IntPtr.Zero);
@@ -97,13 +104,6 @@ namespace System
                        }
                }
 
-               internal __ComObject (IntPtr pItf)
-               {
-                       Guid iid = IID_IUnknown;
-                       int hr = Marshal.QueryInterface (pItf, ref iid, out iunknown);
-                       Marshal.ThrowExceptionForHR (hr);
-               }
-
                private static Guid GetCLSID (Type t)
                {
                        if (t.IsImport)