// 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); }
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; }
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); }
/// <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 }