// constructor
            public WebBrowserSiteEx(WebBrowserEx host) : base(host)
            {
                // This code causes problems on XP
                if (host.Version.Major >= 9)
                {
                    _host = host;

                    // get the CCW object for this
                    _unkOuter = Marshal.GetIUnknownForObject(this);
                    Marshal.AddRef(_unkOuter);
                    try
                    {
                        // aggregate the CCW object with the helper Inner object
                        _inner = new Inner(this);
                        _unkInnerAggregated = Marshal.CreateAggregatedObject(_unkOuter, _inner);

                        // obtain private WebBrowserSite COM interfaces
                        _baseIDocHostUIHandler = (NativeMethods.IDocHostUIHandler)Marshal.GetTypedObjectForIUnknown(_unkInnerAggregated, typeof(NativeMethods.IDocHostUIHandler));
                    }
                    finally
                    {
                        Marshal.Release(_unkOuter);
                    }
                }
            }
        public void CreateAggregatedInstance(
            string assemblyName, string typeName, IComAggregator outerObject)
        {
            IntPtr pOuter = IntPtr.Zero;
            IntPtr pInner = IntPtr.Zero;

            try
            {
                // We use Marshal.CreateAggregatedObject to create a CCW where
                // the inner object (the target managed add-in) is aggregated
                // with the supplied outer object (the shim).
                pOuter = Marshal.GetIUnknownForObject(outerObject);
                object innerObject =
                    AppDomain.CurrentDomain.CreateInstanceAndUnwrap(
                        assemblyName, typeName);
                pInner = Marshal.CreateAggregatedObject(pOuter, innerObject);

                // Make sure the shim has a pointer to the add-in.
                outerObject.SetInnerPointer(pInner);
            }
            finally
            {
                if (pOuter != IntPtr.Zero)
                {
                    Marshal.Release(pOuter);
                }
                if (pInner != IntPtr.Zero)
                {
                    Marshal.Release(pInner);
                }
            }
        }
Exemple #3
0
        public void CreateAggregatedObject_NonGeneric_ReturnsExpected()
        {
            var    original = new object();
            IntPtr ptr      = Marshal.GetIUnknownForObject(original);

            try
            {
                int    toAggregate       = 1;
                IntPtr aggregatedObject1 = Marshal.CreateAggregatedObject(ptr, (object)toAggregate);
                try
                {
                    Assert.NotEqual(IntPtr.Zero, aggregatedObject1);

                    IntPtr aggregatedObject2 = Marshal.CreateAggregatedObject(ptr, (object)toAggregate);
                    Assert.NotEqual(IntPtr.Zero, aggregatedObject2);
                    Assert.NotEqual(aggregatedObject1, aggregatedObject2);
                }
                finally
                {
                    Marshal.Release(aggregatedObject1);
                }
            }
            finally
            {
                Marshal.Release(ptr);
            }
        }
Exemple #4
0
            int Native.IClassFactory.CreateInstance(IntPtr pUnkOuter, Guid riid, out IntPtr ppvObject)
            {
                // query the current instance for a given interface
                ppvObject = IntPtr.Zero;
                var pUnk = pUnkOuter != IntPtr.Zero ? Marshal.CreateAggregatedObject(pUnkOuter, this) : Marshal.GetIUnknownForObject(this);

                try { return(Marshal.QueryInterface(pUnk, ref riid, out ppvObject)); }
                finally { Marshal.Release(pUnk); }
            }
Exemple #5
0
        public IntPtr Create(string typeName, IntPtr outer)
        {
            var type = Type.GetType(typeName);

            if (type == null)
            {
                throw new InvalidOperationException("Invalid type name.");
            }
            return(Marshal.CreateAggregatedObject(outer, Activator.CreateInstance(type)));
        }
Exemple #6
0
        /// <summary>
        /// Creates a new instance of fullQualifiedTypeName and call outerObject to publish the instance
        /// to the outer caller.
        /// </summary>
        /// <param name="assemblyName">name or strong name where the target type is located</param>
        /// <param name="fullQualifiedTypeName">type to create</param>
        /// <param name="outerAggregator">caller as outer aggregator</param>
        /// <param name="shimHost">outer shim host</param>
        /// <exception cref="ArgumentNullException">argument is null or empty</exception>
        /// <exception cref="MissingMethodException">no matching public constructor was found</exception>/param>
        /// <exception cref="TypeLoadException">typename was not found in assemblyName</exception>/param>
        /// <exception cref="FileNotFoundException">assemblyName was not found</exception>/param>
        /// <exception cref="MethodAccessException">the caller does not have permission to call this constructor</exception>/param>
        /// <exception cref="AppDomainUnloadedException">the operation is attempted on an unloaded application domain.</exception>/param>
        /// <exception cref="BadImageFormatException">assemblyName is not a valid assembly</exception>
        /// <exception cref="FileLoadException">an assembly or module was loaded twice with two different evidences</exception>
        /// <exception cref="InvalidOperationException">unexpected error</exception>
        public void CreateAggregatedInstance(string assemblyName, string fullQualifiedTypeName, IOuterComAggregator outerAggregator, IShimHost shimHost)
        {
            if (String.IsNullOrWhiteSpace(assemblyName))
            {
                throw new ArgumentNullException("assemblyName");
            }
            if (String.IsNullOrWhiteSpace(fullQualifiedTypeName))
            {
                throw new ArgumentNullException("fullQualifiedTypeName");
            }
            if (null == outerAggregator)
            {
                throw new ArgumentNullException("outerAggregator");
            }

            IntPtr pOuter = IntPtr.Zero;
            IntPtr pInner = IntPtr.Zero;

            try
            {
                pOuter = Marshal.GetIUnknownForObject(outerAggregator);
                if (IntPtr.Zero != pOuter)
                {
                    object innerObject = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assemblyName, fullQualifiedTypeName);
                    TrySetShimHost(innerObject, shimHost);
                    pInner = Marshal.CreateAggregatedObject(pOuter, innerObject);
                    if (IntPtr.Zero != pInner)
                    {
                        outerAggregator.SetInnerAddin(pInner);
                    }
                }

                if (IntPtr.Zero == pOuter || IntPtr.Zero == pInner)
                {
                    throw new InvalidOperationException("Unexpected result while getting IUnkown Pointer.");
                }
            }
            catch (Exception exception)
            {
                NetOffice.DebugConsole.Default.WriteException(exception);
                throw;
            }
            finally
            {
                if (IntPtr.Zero != pOuter)
                {
                    Marshal.Release(pOuter);
                }
                if (IntPtr.Zero != pInner)
                {
                    Marshal.Release(pInner);
                }
                Marshal.ReleaseComObject(outerAggregator);
            }
        }
Exemple #7
0
            public ImprovedClass()
            {
                var typeBaseIComInterface = typeof(OldLibrary.BaseClass).GetInterfaces().First((t) =>
                                                                                               t.GUID == typeof(IComInterface).GUID); // get OldLibrary.BaseClass.IComInterface

                this.unkBaseIComInterface = Marshal.GetComInterfaceForObject(this, typeBaseIComInterface, CustomQueryInterfaceMode.Ignore);

                this.unkBaseShim      = Marshal.CreateAggregatedObject(this.unkBaseIComInterface, new Inner(this.unkBaseIComInterface));
                this.baseComInterface = (IComInterface)Marshal.GetTypedObjectForIUnknown(this.unkBaseShim, typeof(IComInterface));

                ((IComInterface)this).ComMethod(this);                 // works!
            }
        private static object CreateAggregatedObject(object pUnkOuter, object comObject)
        {
            IntPtr outerPtr = Marshal.GetIUnknownForObject(pUnkOuter);

            try
            {
                IntPtr innerPtr = Marshal.CreateAggregatedObject(outerPtr, comObject);
                return(Marshal.GetObjectForIUnknown(innerPtr));
            }
            finally
            {
                // Decrement the above 'Marshal.GetIUnknownForObject()'
                Marshal.Release(outerPtr);
            }
        }
            public object CreateAggregatedObject(object managedObject)
            {
                Contract.ThrowIfNull(managedObject, "managedObject");

                // 1. Create our native COM object that will aggregate "managedObject"
                var wrapperUnknown = BlindAggregatorFactory.CreateWrapper(); // AddRef'ed

                try
                {
                    // 2. Ask the CLR to create an object supporting aggregation for "managedObject"
                    var innerUnknown = Marshal.CreateAggregatedObject(wrapperUnknown, managedObject); // AddRef'ed
                    try
                    {
                        // 3. Create a GC Handle to the managed object for later retrieval
                        var handle     = GCHandle.Alloc(managedObject, GCHandleType.Normal);
                        var freeHandle = true;
                        try
                        {
                            // 4. Now, link our native (aggregator) with the IUnknown of the CLR inner object, the
                            //    GC Handle managed and the GC handle of the managed object.
                            //    GC handle will be free by the native wrapper.
                            BlindAggregatorFactory.SetInnerObject(wrapperUnknown, innerUnknown, GCHandle.ToIntPtr(handle));
                            freeHandle = false;
                        }
                        finally
                        {
                            if (freeHandle)
                            {
                                handle.Free();
                            }
                        }

                        OnAggregatedObjectCreated();

                        // 5. All done: Ask the CLR to create an RCW for the native aggregator
                        object wrapperRCW = Marshal.GetObjectForIUnknown(wrapperUnknown);
                        return((IComWrapper)wrapperRCW);
                    }
                    finally
                    {
                        Marshal.Release(innerUnknown);
                    }
                }
                finally
                {
                    Marshal.Release(wrapperUnknown);
                }
            }
Exemple #10
0
            public static object CreateAggregatedObject(object pUnkOuter, object comObject)
            {
                Debug.Assert(pUnkOuter != null && comObject != null);
                IntPtr outerPtr = Marshal.GetIUnknownForObject(pUnkOuter);

                try
                {
                    IntPtr innerPtr = Marshal.CreateAggregatedObject(outerPtr, comObject);
                    return(Marshal.GetObjectForIUnknown(innerPtr));
                }
                finally
                {
                    // Decrement the above 'Marshal.GetIUnknownForObject()'
                    Marshal.ReleaseComObject(pUnkOuter);
                }
            }
            IntPtr _unkAggregated;          // aggregated proxy

            public BaseClassComProxy(object outer)
            {
                _outer      = new WeakReference(outer);
                _interfaces = outer.GetType().BaseType.GetInterfaces();
                var unkOuter = Marshal.GetIUnknownForObject(outer);

                try
                {
                    // CreateAggregatedObject does AddRef on this
                    // se we provide IDispose for proper shutdown
                    _unkAggregated = Marshal.CreateAggregatedObject(unkOuter, this);
                }
                finally
                {
                    Marshal.Release(unkOuter);
                }
            }
        internal static ComProxy Create(IntPtr outer, object obj, IDisposable disp)
        {
            if (outer == IntPtr.Zero)
            {
                throw Fx.AssertAndThrow("Outer cannot be null");
            }
            IntPtr zero = IntPtr.Zero;

            zero = Marshal.CreateAggregatedObject(outer, obj);
            int num = Marshal.AddRef(zero);

            if (3 == num)
            {
                Marshal.Release(zero);
            }
            Marshal.Release(zero);
            return(new ComProxy(zero, disp));
        }
            // constructor
            public ImprovedClass()
            {
                // get OldLibrary.BaseClass.IComInterface via reflection
                var typeBaseIComInterface = typeof(OldLibrary.BaseClass).GetInterfaces().First((t) =>
                                                                                               t.GUID == typeof(NewLibrary.IComInterface).GUID);

                // get the COM interface for OldLibrary.BaseClass.IComInterface
                _unkBaseIComInterface = Marshal.GetComInterfaceForObject(this, typeBaseIComInterface, CustomQueryInterfaceMode.Ignore);
                Marshal.AddRef(_unkBaseIComInterface);                 // protect _unkBaseIComInterface

                // aggregate it with a helper Inner object
                _inner = new Inner(_unkBaseIComInterface);
                _unkInnerAggregated = Marshal.CreateAggregatedObject(_unkBaseIComInterface, _inner);

                // turn private OldLibrary.BaseClass.IComInterface into NewLibrary.IComInterface
                _baseIComInterface = (IComInterface)Marshal.GetTypedObjectForIUnknown(_unkInnerAggregated, typeof(NewLibrary.IComInterface));

                Marshal.Release(_unkBaseIComInterface);
            }
Exemple #14
0
            public DCWebBrowserSite(WebBrowser host) : base(host)
            {
                // get the CCW object for this
                _unkOuter = Marshal.GetIUnknownForObject(this);
                Marshal.AddRef(_unkOuter);
                try
                {
                    // aggregate the CCW object with the helper Inner object
                    _inner = new Inner(this);
                    _unkInnerAggregated = Marshal.CreateAggregatedObject(_unkOuter, _inner);

                    // obtain private WebBrowserSite COM interfaces
                    _baseIDocHostUIHandler = (UnsafeNativeMethods.IDocHostUIHandler)Marshal.GetTypedObjectForIUnknown(_unkInnerAggregated, typeof(UnsafeNativeMethods.IDocHostUIHandler));
                }
                finally
                {
                    Marshal.Release(_unkOuter);
                }
            }
Exemple #15
0
        internal static ComProxy Create(IntPtr outer, object obj, IDisposable disp)
        {
            if (outer == IntPtr.Zero)
            {
                throw Fx.AssertAndThrow("Outer cannot be null");
            }
            IntPtr inner = IntPtr.Zero;

            inner = Marshal.CreateAggregatedObject(outer, obj);
            int refCount = Marshal.AddRef(inner);

            // Workaround for the CLR ref count issue.
            if (3 == refCount)
            {
                Marshal.Release(inner);
            }
            Marshal.Release(inner);
            return(new ComProxy(inner, disp));
        }
Exemple #16
0
            public void CreateInstance(
                [MarshalAs(UnmanagedType.Interface)] object pUnkOuter,
                ref Guid riid,
                [MarshalAs(UnmanagedType.Interface)] out object ppvObject)
            {
                if (riid != Marshal.IID_IUnknown)
                {
                    bool found = false;

                    // Verify the class implements the desired interface
                    foreach (Type i in this.classType.GetInterfaces())
                    {
                        if (i.GUID == riid)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        // E_NOINTERFACE
                        throw new InvalidCastException();
                    }
                }

                ppvObject = Activator.CreateInstance(this.classType);
                if (pUnkOuter != null)
                {
                    try
                    {
                        IntPtr outerPtr = Marshal.GetIUnknownForObject(pUnkOuter);
                        IntPtr innerPtr = Marshal.CreateAggregatedObject(outerPtr, ppvObject);
                        ppvObject = Marshal.GetObjectForIUnknown(innerPtr);
                    }
                    finally
                    {
                        // Decrement the above 'Marshal.GetIUnknownForObject()'
                        Marshal.ReleaseComObject(pUnkOuter);
                    }
                }
            }
            // constructor
            public ImprovedWebBrowserSite(WebBrowser host) :
                base(host)
            {
                // get WebBrowserSiteBase.IOleClientSite via reflection
                var typeBaseIOleClientSite = typeof(WebBrowserSiteBase).GetInterfaces().First((t) =>
                                                                                              t.GUID == typeof(IOleClientSite).GUID);

                // get the COM interface for WebBrowserSiteBase.IOleClientSite
                _unkBaseIOleClientSite = Marshal.GetComInterfaceForObject(this, typeBaseIOleClientSite, CustomQueryInterfaceMode.Ignore);
                Marshal.AddRef(_unkBaseIOleClientSite);                 // protect _unkBaseIOleClientSite

                // aggregate it with the helper Inner object
                _inner = new Inner(_unkBaseIOleClientSite);
                _unkInnerAggregated = Marshal.CreateAggregatedObject(_unkBaseIOleClientSite, _inner);

                // turn private WebBrowserSiteBase.IOleClientSite into our own IOleClientSite
                _baseIOleClientSite = (IOleClientSite)Marshal.GetTypedObjectForIUnknown(_unkInnerAggregated, typeof(IOleClientSite));

                Marshal.Release(_unkBaseIOleClientSite);
            }
            // constructor
            public ImprovedWebBrowserSite(WebBrowser host) :
                base(host)
            {
                // get the CCW object for this
                _unkOuter = Marshal.GetIUnknownForObject(this);
                Marshal.AddRef(_unkOuter);
                try
                {
                    // aggregate the CCW object with the helper Inner object
                    _inner = new Inner(this);
                    _unkInnerAggregated = Marshal.CreateAggregatedObject(_unkOuter, _inner);

                    // turn private WebBrowserSiteBase.IOleClientSite into our own IOleClientSite
                    _baseIOleClientSite = (IOleClientSite)Marshal.GetTypedObjectForIUnknown(_unkInnerAggregated, typeof(IOleClientSite));
                }
                finally
                {
                    Marshal.Release(_unkOuter);
                }
            }
Exemple #19
0
        public void CreateAggregatedObject_ObjectNotCollectible_ReturnsExpected()
        {
            var    original = new object();
            IntPtr ptr      = Marshal.GetIUnknownForObject(original);

            try
            {
                AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.RunAndCollect);
                ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule("Module");
                TypeBuilder     typeBuilder     = moduleBuilder.DefineType("Type");
                Type            type            = typeBuilder.CreateType();

                object o = Activator.CreateInstance(type);
                Assert.Throws <NotSupportedException>(() => Marshal.CreateAggregatedObject(ptr, o));
                Assert.Throws <NotSupportedException>(() => Marshal.CreateAggregatedObject <object>(ptr, o));
            }
            finally
            {
                Marshal.Release(ptr);
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="outerObject">The object that needs interface requests filtered</param>
        /// <param name="queryForType">determines whether we call QueryInterface for the interface or not</param>
        /// <remarks>if the passed in outerObject is known to point to the correct vtable for the interface, then queryForType can be false</remarks>
        /// <returns>if outerObject is IntPtr.Zero, then a null wrapper, else an aggregated wrapper</returns>
        public RestrictComInterfaceByAggregation(IntPtr outerObject, bool queryForType = true)
        {
            if (queryForType)
            {
                var IID = typeof(T).GUID;
                if (ComHelper.HRESULT_FAILED(Marshal.QueryInterface(outerObject, ref IID, out _outerObject)))
                {
                    // allow null wrapping here
                    return;
                }
            }
            else
            {
                _outerObject = outerObject;
                Marshal.AddRef(_outerObject);
            }

            var aggObjPtr = Marshal.CreateAggregatedObject(_outerObject, this);

            WrappedObject = (T)Marshal.GetObjectForIUnknown(aggObjPtr); // when this CCW object gets released, it will free the aggObjInner (well, after GC)
            Marshal.Release(aggObjPtr);                                 // _wrappedObject holds a reference to this now
        }
Exemple #21
0
        public void CreateAggregatedInstance(
            string assemblyName, string typeName, IComAggregator outerObject)
        {
            IntPtr pOuter = IntPtr.Zero;
            IntPtr pInner = IntPtr.Zero;

            try
            {
                // We use Marshal.CreateAggregatedObject to create a CCW where
                // the inner object (the target managed add-in) is aggregated
                // with the supplied outer object (the shim).
                pOuter = Marshal.GetIUnknownForObject(outerObject);
                object innerObject =
                    AppDomain.CurrentDomain.CreateInstanceAndUnwrap(
                        assemblyName, typeName);
                pInner = Marshal.CreateAggregatedObject(pOuter, innerObject);

                // Make sure the shim has a pointer to the add-in.
                outerObject.SetInnerPointer(pInner);
            }
            finally
            {
                if (pOuter != IntPtr.Zero)
                {
                    Marshal.Release(pOuter);
                }
                if (pInner != IntPtr.Zero)
                {
                    Marshal.Release(pInner);
                }

                // FIX: Bug discovered after release of 2.3.1.0.
                // We call ReleaseComObject on the outer object (ConnectProxy)
                // to make sure we delete the RCW, and prevent the CLR from
                // holding onto it indefinitely (and keeping the host alive).
                Marshal.ReleaseComObject(outerObject);
            }
        }
 public void CreateAggregatedObject_AlreadyHasContainer_ThrowsArgumentException()
 {
     var o1 = new object();
     IntPtr ptr1 = Marshal.GetIUnknownForObject(o1);
     try
     {
         var o2 = new object();
         IntPtr ptr2 = Marshal.GetIUnknownForObject(o2);
         try
         {
             AssertExtensions.Throws<ArgumentException>("o", () => Marshal.CreateAggregatedObject(ptr1, o1));
             AssertExtensions.Throws<ArgumentException>("o", () => Marshal.CreateAggregatedObject(ptr1, o2));
         }
         finally
         {
             Marshal.Release(ptr2);
         }
     }
     finally
     {
         Marshal.Release(ptr1);
     }
 }
Exemple #23
0
        int IVsAggregatableProjectFactoryCorrected.PreCreateForOuter(IntPtr outerProjectIUnknown, out IntPtr projectIUnknown)
        {
            projectIUnknown = IntPtr.Zero;  // always initialize out parameters of COM interfaces!

            var newProject = PreCreateForOuter(outerProjectIUnknown);

            var newProjectIUnknown = IntPtr.Zero;
            var localRegistry      = (ILocalRegistryCorrected)this._serviceProvider.GetService(typeof(SLocalRegistry));

            Debug.Assert(localRegistry != null, "Could not get the ILocalRegistry object");
            if (localRegistry == null)
            {
                throw new InvalidOperationException();
            }
            var clsid    = typeof(Microsoft.VisualStudio.ProjectAggregator.CProjectAggregatorClass).GUID;
            var riid     = VSConstants.IID_IUnknown;
            var dwClsCtx = (uint)CLSCTX.CLSCTX_INPROC_SERVER;
            var aggregateProjectIUnknown = IntPtr.Zero;
            IVsProjectAggregator2 vsProjectAggregator2 = null;

            try
            {
                ErrorHandler.ThrowOnFailure(localRegistry.CreateInstance(clsid, outerProjectIUnknown, ref riid, dwClsCtx, out aggregateProjectIUnknown));

                // If we have a non-NULL punkOuter then we need to create a COM aggregated object with that punkOuter,
                // if not then we are the top of the aggregation.
                if (outerProjectIUnknown != IntPtr.Zero)
                {
                    newProjectIUnknown = Marshal.CreateAggregatedObject(outerProjectIUnknown, newProject);
                }
                else
                {
                    newProjectIUnknown = Marshal.CreateAggregatedObject(aggregateProjectIUnknown, newProject);;
                }

                vsProjectAggregator2 = (IVsProjectAggregator2)Marshal.GetObjectForIUnknown(aggregateProjectIUnknown);
                if (vsProjectAggregator2 != null)
                {
                    vsProjectAggregator2.SetMyProject(newProjectIUnknown);
                }

                // We return the native ProjectAggregator COM object as the project created by our project
                // factory. This ProjectAggregator main purpose is to manage the fact that the punkInner pointer
                // for the project aggregation is not known until after IVsAggregateProject::SetInnerProject is
                // called. This native object has a special implementation of QueryInterface that can handle
                // the SetInnerProject mechanism. The ProjectAggregator will first delegate QueryInterface
                // calls to our managed project and then delegates to the inner Project.
                // Note: we need to return an AddRef'ed IUnknown (AddRef comes from CreateInstance call).
                projectIUnknown          = aggregateProjectIUnknown;
                aggregateProjectIUnknown = IntPtr.Zero;
            }
            finally
            {
                if (newProjectIUnknown != IntPtr.Zero)
                {
                    Marshal.Release(newProjectIUnknown);
                }
                if (aggregateProjectIUnknown != IntPtr.Zero)
                {
                    Marshal.Release(aggregateProjectIUnknown);
                }
            }

            if (projectIUnknown == IntPtr.Zero)
            {
                return(VSConstants.E_FAIL);
            }

            return(VSConstants.S_OK);
        }
Exemple #24
0
 public void CreateAggregateObject_NullObject_ThrowsArgumentNullException()
 {
     AssertExtensions.Throws <ArgumentNullException>("o", () => Marshal.CreateAggregatedObject((IntPtr)1, null));
 }
Exemple #25
0
 public void CreateAggregateObject_ZeroPointer_ThrowsArgumentNullException()
 {
     AssertExtensions.Throws <ArgumentNullException>("pOuter", () => Marshal.CreateAggregatedObject(IntPtr.Zero, 1));
 }
Exemple #26
0
 public void CreateAggregatedObject_Unix_ThrowsPlatformNotSupportedException()
 {
     Assert.Throws <PlatformNotSupportedException>(() => Marshal.CreateAggregatedObject(IntPtr.Zero, 1));
 }
Exemple #27
0
        /// <summary>
        /// Aggregate the com server which exposes the specified interface, the Guid of the interface that exposed to
        /// client is the specified guid.
        /// </summary>
        /// <param name="guid">Guid of the interface that specified the interface</param>
        /// <param name="interfaceType">Interface that exposed to client</param>
        /// <param name="classType">Server class that implement the interface</param>
        private void Aggregate(Guid guid, Type interfaceType, Type classType)
        {
            if (guid == null || interfaceType == null || classType == null)
            {
                throw new ArgumentNullException("Parameter should not be null");
            }

            // if already have interface registered with same Guid, action fails
            if (guidTypeDictionary.ContainsKey(guid))
            {
                throw new InvalidOperationException(String.Format("Interface with Guid {0} has already been registered"
                                                                  + " in the server, please unregister the interface before registration!", guid));
            }

            guidTypeDictionary.Add(guid, interfaceType);

            if (interfaceClassDictionary.ContainsKey(interfaceType))
            {
                Type tmpClassType = interfaceClassDictionary[interfaceType];
                // if alreay have another registered class that implements and exposes the same interfae, action fails
                if (tmpClassType != classType)
                {
                    // roll back, remove the previous registration of GUID/Interface
                    guidTypeDictionary.Remove(guid);

                    string errorMsg = String.Format("Can not register the interface {0} which is already exposed and implemented by Class {1} .",
                                                    interfaceType.ToString(),
                                                    tmpClassType.ToString());
                    throw new InvalidOperationException(errorMsg);
                }

                // have already created the instance of the type and maintained the dictionaries.
                return;
            }

            // <Interface Guid, Interface Type>
            interfaceClassDictionary.Add(interfaceType, classType);

            // <Class Type, Instance>
            // construct a new object instance if do not have, aggreate the object and store the mapping
            object o = null;

            if (!classInstanceDictionary.ContainsKey(classType))
            {
                // create the new instance
                ConstructorInfo ci = classType.GetConstructor(Type.EmptyTypes);
                o = ci.Invoke(new Object[0]);
                classInstanceDictionary.Add(classType, o);

                // Set the aggregator
                IInnerHoldingOuterReference ins = o as IInnerHoldingOuterReference;
                if (ins != null)
                {
                    Console.WriteLine("Set Aggregator for " + o.GetType());
                    ins.Outer = this;
                }

                // Aggregate the object
                IntPtr pUnk          = Marshal.GetIUnknownForObject(this);
                IntPtr pInnerIUnkPtr = Marshal.CreateAggregatedObject(pUnk, o);

                // This release is to ensure that ‘this’ don’t hold a ref-count on itself,
                // which could prevent GC from collecting ‘this’ instance at the end
                Marshal.Release(pUnk);
                innerHORCCWList.AddLast(pInnerIUnkPtr);

                // Inform the aggregated objects who have subscribed to the UnAggregation event
                if (aggregationEvent != null)
                {
                    aggregationEvent(guid, interfaceType, classType);
                }
            }
        }
Exemple #28
0
        private IntPtr Initialize(Func <object> createInnerObject)
        {
            try
            {
                // implement IUnknown methods
                _queryInterfaceMethod = delegate(IntPtr pUnk, ref Guid iid, out IntPtr ppv)
                {
                    lock (this)
                    {
                        // delegate anything but IID_IUnknown to the aggregated object
                        if (IID_IUnknown == iid)
                        {
                            ppv = _outerObject;
                            Marshal.AddRef(_outerObject);
                            return(S_OK);
                        }
                        return(Marshal.QueryInterface(_aggregatedObject, ref iid, out ppv));
                    }
                };

                _addRefMethod = delegate(IntPtr pUnk)
                {
                    lock (this)
                    {
                        return(++_refCount);
                    }
                };

                _releaseMethod = delegate(IntPtr pUnk)
                {
                    lock (this)
                    {
                        if (0 == --_refCount)
                        {
                            Free();
                        }
                        return(_refCount);
                    }
                };

                // create the IUnknown vtable
                var vtable = new UnkVtable();
                vtable.pQueryInterface = Marshal.GetFunctionPointerForDelegate(_queryInterfaceMethod);
                vtable.pAddRef         = Marshal.GetFunctionPointerForDelegate(_addRefMethod);
                vtable.pRelease        = Marshal.GetFunctionPointerForDelegate(_releaseMethod);

                _pVtable = Marshal.AllocCoTaskMem(Marshal.SizeOf(vtable));
                Marshal.StructureToPtr(vtable, _pVtable, false);

                // create the IUnknown object
                var unkObject = new UnkObject();
                unkObject.pVtable = _pVtable;
                _outerObject      = Marshal.AllocCoTaskMem(Marshal.SizeOf(unkObject));
                Marshal.StructureToPtr(unkObject, _outerObject, false);

                // pin the managed ComWrapper instance
                _gcHandle = GCHandle.Alloc(this, GCHandleType.Normal);

                // create and aggregate the inner object
                _aggregatedObject = Marshal.CreateAggregatedObject(_outerObject, createInnerObject());

                return(_outerObject);
            }
            catch
            {
                Free();
                throw;
            }
        }
        public void CreateAggregatedObject_T_ThrowsNotSupportedException()
        {
            object value = new object();

            Assert.Throws <NotSupportedException>(() => Marshal.CreateAggregatedObject <object>(IntPtr.Zero, value));
        }
 // CreateAggregatedWrapper returns a reference counted COM pointer to the aggregated object
 // When it gets released in COM, it should in turn release the internal CCW reference on our AggregationHelper object
 public static IntPtr CreateAggregatedWrapper(object objectToWrap, Type[] supportedTypes)
 {
     return(Marshal.CreateAggregatedObject(Marshal.GetIUnknownForObject(objectToWrap),       // aggregated object will own this COM reference, but this is fine, as it is really a managed object
                                           new AggregationHelper(objectToWrap, supportedTypes)));
 }