Inheritance: MarshalByRefObject
Example #1
0
		// Private. Objects must be created with CreateProxy.
		ComInteropProxy (Type t)
			: base (t)
		{
			// object only created here
			// .ctor is called later
			com_object = __ComObject.CreateRCW (t);
		}
Example #2
0
        [System.Security.SecurityCritical]  // auto-generated
        internal void ReleaseAllData()
        {
            // Synchronize access to the map.
            lock (this)
            {
                // If the map hasn't been allocated, then there is nothing to do.
                if (m_ObjectToDataMap != null)
                {
                    foreach (Object o in m_ObjectToDataMap.Values)
                    {
                        // Note: the value could be an object[]
                        // We are fine for now as object[] doesn't implement IDisposable nor derive from __ComObject

                        // If the object implements IDisposable, then call Dispose on it.
                        IDisposable DisposableObj = o as IDisposable;
                        if (DisposableObj != null)
                        {
                            DisposableObj.Dispose();
                        }

                        // If the object is a derived from __ComObject, then call Marshal.ReleaseComObject on it.
                        __ComObject ComObj = o as __ComObject;
                        if (ComObj != null)
                        {
                            Marshal.ReleaseComObject(ComObj);
                        }
                    }

                    // Set the map to null to indicate it has been cleaned up.
                    m_ObjectToDataMap = null;
                }
            }
        }
        public override bool Equals(object obj)
        {
            this.CheckIUnknown();
            if (obj == null)
            {
                return(false);
            }
            __ComObject _ComObject = obj as __ComObject;

            return(_ComObject != null && this.iunknown == _ComObject.IUnknown);
        }
Example #4
0
        public override bool Equals(object obj)
        {
            CheckIUnknown();
            if (obj == null)
            {
                return(false);
            }

            __ComObject co = obj as __ComObject;

            if ((object)co == null)
            {
                return(false);
            }
            return(iunknown == co.IUnknown);
        }
Example #5
0
 internal void ReleaseAllData()
 {
     lock (this)
     {
         if (this.m_ObjectToDataMap != null)
         {
             foreach (object obj2 in this.m_ObjectToDataMap.Values)
             {
                 IDisposable disposable = obj2 as IDisposable;
                 if (disposable != null)
                 {
                     disposable.Dispose();
                 }
                 __ComObject o = obj2 as __ComObject;
                 if (o != null)
                 {
                     Marshal.ReleaseComObject(o);
                 }
             }
             this.m_ObjectToDataMap = null;
         }
     }
 }
Example #6
0
 internal void ReleaseAllData()
 {
     lock (this)
     {
         if (this.m_ObjectToDataMap == null)
         {
             return;
         }
         foreach (object item_0 in (IEnumerable)this.m_ObjectToDataMap.Values)
         {
             IDisposable local_3 = item_0 as IDisposable;
             if (local_3 != null)
             {
                 local_3.Dispose();
             }
             __ComObject local_4 = item_0 as __ComObject;
             if (local_4 != null)
             {
                 Marshal.ReleaseComObject((object)local_4);
             }
         }
         this.m_ObjectToDataMap = (Hashtable)null;
     }
 }
Example #7
0
        /// <summary>
        /// Returns the existing RCW or create a new RCW from the COM interface pointer
        /// NOTE: This does not do any unboxing at all. 
        /// </summary>
        /// <param name="expectedContext">
        /// The current context of this thread. If it is passed and is not Default, we'll check whether the
        /// returned RCW from cache matches this expected context. If it is not a match (from a different 
        /// context, and is not free threaded), we'll go ahead ignoring the cached entry, and create a new
        /// RCW instead - which will always end up in the current context
        /// We'll skip the check if current == ContextCookie.Default. 
        /// </param>
        private static object ComInterfaceToComObjectInternal_NoCache(
            IntPtr pComItf,
            IntPtr pComIdentityIUnknown,
            RuntimeTypeHandle interfaceType,
            RuntimeTypeHandle classTypeInSignature,
            ContextCookie expectedContext,
            CreateComObjectFlags flags,
            out string className
            )
        {
            className = null;

            //
            // Lookup RCW in global RCW cache based on the identity IUnknown
            //
            __ComObject comObject = ComObjectCache.Lookup(pComIdentityIUnknown);

            if (comObject != null)
            {
                bool useThisComObject = true;

                if (!expectedContext.IsDefault)
                {
                    //
                    // Make sure the returned RCW matches the context we specify (if any)
                    //
                    if (!comObject.IsFreeThreaded &&
                        !comObject.ContextCookie.Equals(expectedContext))
                    {
                        //
                        // This is a mismatch.
                        // We only care about context for WinRT factory RCWs (which is the only place we are
                        // passing in the context right now). 
                        // When we get back a WinRT factory RCW created in a different context. This means the
                        // factory is a singleton, and the returned IActivationFactory could be either one of 
                        // the following:
                        // 1) A raw pointer, and it acts like a free threaded object
                        // 2) A proxy that is used across different contexts. It might maintain a list of contexts
                        // that it is marshaled to, and will fail to be called if it is not marshaled to this 
                        // context yet.
                        //
                        // In this case, it is unsafe to use this RCW in this context and we should proceed
                        // to create a duplicated one instead. It might make sense to have a context-sensitive
                        // RCW cache but I don't think this case will be common enough to justify it
                        //
                        // @TODO: Check for DCOM proxy as well
                        useThisComObject = false;
                    }
                }

                if (useThisComObject)
                {
                    //
                    // We found one - AddRef and return
                    //
                    comObject.AddRef();
                    return comObject;
                }
            }

            string winrtClassName = null;

            bool isSealed = false;

            if (!classTypeInSignature.IsNull())
            {
                isSealed = classTypeInSignature.IsSealed();
            }

            //
            // Only look at runtime class name if the class type in signature is not sealed
            // NOTE: In the case of System.Uri, we are not pass the class type, only the interface
            //
            if (!isSealed &&
                (flags & CreateComObjectFlags.SkipTypeResolutionAndUnboxing) == 0)
            {
                IntPtr pInspectable;

                bool needRelease = false;

                if (interfaceType.IsSupportIInspectable())
                {
                    //
                    // Use the interface pointer as IInspectable as we know it is indeed a WinRT interface that
                    // derives from IInspectable
                    //
                    pInspectable = pComItf;
                }
                else if ((flags & CreateComObjectFlags.IsWinRTObject) != 0)
                {
                    //
                    // Otherwise, if someone tells us that this is a WinRT object, but we don't have a 
                    // IInspectable interface at hand, we'll QI for it
                    //
                    pInspectable = McgMarshal.ComQueryInterfaceNoThrow(pComItf, ref Interop.COM.IID_IInspectable);
                    needRelease = true;
                }
                else
                {
                    pInspectable = default(IntPtr);
                }

                try
                {
                    if (pInspectable != default(IntPtr))
                    {
                        className = McgComHelpers.GetRuntimeClassName(pInspectable);
                        winrtClassName = className;
                    }
                }
                finally
                {
                    if (needRelease && pInspectable != default(IntPtr))
                    {
                        McgMarshal.ComRelease(pInspectable);
                        pInspectable = default(IntPtr);
                    }
                }
            }

            //
            // 1. Prefer using the class returned from GetRuntimeClassName
            // 2. Otherwise use the class (if there) in the signature
            // 3. Out of options - create __ComObject
            //
            RuntimeTypeHandle classTypeToCreateRCW = default(RuntimeTypeHandle);
            RuntimeTypeHandle interfaceTypeFromName = default(RuntimeTypeHandle);

            if (!String.IsNullOrEmpty(className))
            {
                if (!McgModuleManager.TryGetClassTypeFromName(className, out classTypeToCreateRCW))
                {
                    //
                    // If we can't find the class name in our map, try interface as well
                    // Such as IVector<Int32>
                    // This apparently won't work if we haven't seen the interface type in MCG
                    //
                    McgModuleManager.TryGetInterfaceTypeFromName(className, out interfaceTypeFromName);
                }
            }

            if (classTypeToCreateRCW.IsNull())
                classTypeToCreateRCW = classTypeInSignature;

            // Use identity IUnknown to create the new RCW
            // @TODO: Transfer the ownership of ref count to the RCW
            if (classTypeToCreateRCW.IsNull())
            {
                //
                // Create a weakly typed RCW because we have no information about this particular RCW
                // @TODO - what if this RCW is not seen by MCG but actually exists in WinMD and therefore we
                // are missing GCPressure and ComMarshallingType information for this object?
                //
                comObject = new __ComObject(pComIdentityIUnknown, default(RuntimeTypeHandle));
            }
            else
            {
                //
                // Create a strongly typed RCW based on RuntimeTypeHandle
                //
                comObject = CreateComObjectInternal(classTypeToCreateRCW, pComIdentityIUnknown);            // Use identity IUnknown to create the new RCW
            }

#if DEBUG
            //
            // Remember the runtime class name for debugging purpose
            // This way you can tell what the class name is, even when we failed to create a strongly typed
            // RCW for it
            //
            comObject.m_runtimeClassName = className;
#endif

            //
            // Make sure we QI for that interface
            //
            if (!interfaceType.IsNull())
            {
                comObject.QueryInterface_NoAddRef_Internal(interfaceType, /* cacheOnly= */ false, /* throwOnQueryInterfaceFailure= */ false);
            }

            return comObject;
        }
Example #8
0
        internal static __ComGenericInterfaceDispatcher CreateGenericComDispatcher(RuntimeTypeHandle genericDispatcherDef, RuntimeTypeHandle[] genericArguments, __ComObject comThisPointer)
        {
#if !RHTESTCL && !CORECLR && !CORERT
            Debug.Assert(genericDispatcherDef.IsGenericTypeDefinition());
            Debug.Assert(genericArguments != null && genericArguments.Length > 0);

            RuntimeTypeHandle instantiatedDispatcherType;
            if (!Internal.Runtime.TypeLoader.TypeLoaderEnvironment.Instance.TryGetConstructedGenericTypeForComponents(genericDispatcherDef, genericArguments, out instantiatedDispatcherType))
                return null;    // ERROR

            __ComGenericInterfaceDispatcher dispatcher = (__ComGenericInterfaceDispatcher)InteropExtensions.RuntimeNewObject(instantiatedDispatcherType);
            dispatcher.m_comObject = comThisPointer;

            return dispatcher;
#else
            return null;
#endif
        }
Example #9
0
		internal ComInteropProxy (IntPtr pUnk, Type t)
			: base (t)
		{
			com_object = new __ComObject (pUnk);
			CacheProxy ();
		}
Example #10
0
        internal static bool WalkOneRCW(__ComObject comObject)
        {
            __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef();

            s_currentComObjectToWalk = comObject;

            //
            // Start building references from this RCW to all dependent CCWs
            //
            // NOTE: StdCallCOOP is used instead of Calli to avoid deadlock
            //
            int hr = CalliIntrinsics.StdCallCOOP(
                pJupiterObject->pVtable->pfnFindDependentWrappers,
                pJupiterObject,
                GetDependentWrapperCallbackObject()
                );

            s_currentComObjectToWalk = null;

            return (hr >= 0);
        }
Example #11
0
        /// <summary>
        /// Reporting to Jupiter that we've done one Release to this object instance
        ///
        /// The ref count reporting is needed for Jupiter to determine whether there is something other than
        /// Jupiter and RCW that is holding onto this Jupiter object. If there is, this Jupiter object and
        /// all dependent CCWs must be pegged.
        ///
        /// We typically report the AddRef *after* an AddRef and report the Release *before* a Release
        /// It's better to leak (temporarily) than crash.
        /// </summary>
        internal static void BeforeRelease(__ComObject comObject)
        {
            Debug.Assert(comObject.IsJupiterObject);

            __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef();

            CalliIntrinsics.StdCall<int>(pJupiterObject->pVtable->pfnBeforeRelease, pJupiterObject);
        }
Example #12
0
        /// <summary>
        /// Reporting to Jupiter that we've done one AddRef to this object instance
        ///
        /// The ref count reporting is needed for Jupiter to determine whether there is something other than
        /// Jupiter and RCW that is holding onto this Jupiter object. If there is, this Jupiter object and
        /// all dependent CCWs must be pegged.
        ///
        /// We typically report the AddRef *after* an AddRef and report the Release *before* a Release
        /// It's better to leak (temporarily) than crash.
        /// </summary>
        internal static void AfterAddRef(__ComObject comObject)
        {
            Debug.Assert(comObject.IsJupiterObject);

            __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef();

            //
            // Send out AfterAddRef callbacks to notify Jupiter we've done AddRef for certain interfaces
            // We should do this *after* we made a AddRef because we should never
            // be in a state where report refs > actual refs
            //
            CalliIntrinsics.StdCall<int>(pJupiterObject->pVtable->pfnAfterAddRef, pJupiterObject);
        }
Example #13
0
        /// <summary>
        /// Called after Jupiter RCW has been created
        /// </summary>
        internal static void AfterJupiterRCWCreated(__ComObject comObject)
        {
            __com_IJupiterObject* pJupiterObject = comObject.GetIJupiterObject_NoAddRef();

            //
            // Notify Jupiter that we've created a new RCW for this Jupiter object
            // To avoid surprises, we should notify them before we fire the first AfterAddRef
            //
            CalliIntrinsics.StdCall<int>(pJupiterObject->pVtable->pfnConnect, pJupiterObject);

            //
            // Tell Jupiter that we've done AddRef for IJupiterObject* and IUnknown*
            // It's better to tell them later than earlier (prefering leaking than crashing)
            //
            AfterAddRef(comObject);
            AfterAddRef(comObject);
        }
Example #14
0
        /// <summary>
        /// Called when Jupiter RCW is being created
        /// We do one-time initialization for RCW walker here
        /// </summary>
        internal static void OnJupiterRCWCreated(__ComObject comObject)
        {
            Debug.Assert(comObject.IsJupiterObject);

            if (s_pGCManager == default(IntPtr))
            {
                RCWWalker.Initialize(comObject.GetIJupiterObject_NoAddRef());
            }
        }