예제 #1
0
        // The aggregation magic starts here
        public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
        {
            ppv = IntPtr.Zero;

            if (iid == typeof(T).GUID)
            {
                ppv = _outerObject;
                RdMarshal.AddRef(_outerObject);
                return(CustomQueryInterfaceResult.Handled);
            }

            return(CustomQueryInterfaceResult.Failed);
        }
예제 #2
0
        private void TraceRelease(int rcwCount, ref bool addRef)
        {
            if (!addRef)
            {
                // Temporarily add a ref so that we can safely call IUnknown::Release
                // to report the ref count in the log.
                RdMarshal.AddRef(_pUnk);
            }
            var refCount = RdMarshal.Release(_pUnk);

            Debug.Print($"ComPointer:: Disposed: _pUnk: {RdMarshal.FormatPtr(_pUnk)} _interface: {typeof(TComInterface).Name} - {Interface.GetHashCode()} addRef: {_addRef} rcwCount: {rcwCount} refCount: {refCount}");

            addRef = false;
        }
예제 #3
0
        private ComPointer(IntPtr pUnk, bool addRef)
        {
            var refCount = -1;

            _pUnk = pUnk;
            if (addRef)
            {
                _addRef  = true;
                refCount = RdMarshal.AddRef(_pUnk);
            }

            Interface = (TComInterface)RdMarshal.GetTypedObjectForIUnknown(pUnk, typeof(TComInterface));

            ConstructorPointerPrint(refCount);
        }
예제 #4
0
        /// <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(RdMarshal.QueryInterface(outerObject, ref iid, out _outerObject)))
                {
                    // allow null wrapping here
                    return;
                }
            }
            else
            {
                _outerObject = outerObject;
                RdMarshal.AddRef(_outerObject);
            }

            var clrAggregator = RdMarshal.CreateAggregatedObject(_outerObject, this);

            WrappedObject = (T)RdMarshal.GetObjectForIUnknown(clrAggregator); // when this CCW object gets released, it will free the aggObjInner (well, after GC)
            RdMarshal.Release(clrAggregator);                                 // _wrappedObject holds a reference to this now
        }