public unsafe AgileReference(IObjectReference instance) { if (instance?.ThisPtr == null) { return; } IntPtr agileReference = default; Guid iid = typeof(IUnknownVftbl).GUID; try { Marshal.ThrowExceptionForHR(Platform.RoGetAgileReference( 0 /*AGILEREFERENCE_DEFAULT*/, ref iid, instance.ThisPtr, &agileReference)); #if NET5_0 _agileReference = (IAgileReference) new SingleInterfaceOptimizedObject(typeof(IAgileReference), ObjectReference <ABI.WinRT.Interop.IAgileReference.Vftbl> .Attach(ref agileReference)); #else _agileReference = ABI.WinRT.Interop.IAgileReference.FromAbi(agileReference).AsType <ABI.WinRT.Interop.IAgileReference>(); #endif } catch (TypeLoadException) { _cookie = Git.Value.RegisterInterfaceInGlobal(instance, iid); } finally { MarshalInterface <IAgileReference> .DisposeAbi(agileReference); } }
public static object CreateRcwForComObject(IntPtr ptr) { if (ptr == IntPtr.Zero) { return(null); } IObjectReference identity = GetObjectReferenceForInterface(ptr).As <IUnknownVftbl>(); object keepAliveSentinel = null; Func <IntPtr, System.WeakReference <object> > rcwFactory = (_) => { object runtimeWrapper = null; if (identity.TryAs <IInspectable.Vftbl>(out var inspectableRef) == 0) { var inspectable = new IInspectable(identity); string runtimeClassName = inspectable.GetRuntimeClassName(); runtimeWrapper = TypedObjectFactoryCache.GetOrAdd(runtimeClassName, className => CreateTypedRcwFactory(className))(inspectable); } else if (identity.TryAs <ABI.WinRT.Interop.IWeakReference.Vftbl>(out var weakRef) == 0) { runtimeWrapper = new ABI.WinRT.Interop.IWeakReference(weakRef); } keepAliveSentinel = runtimeWrapper; // We don't take a strong reference on runtimeWrapper at any point, so we need to make sure it lives until it can get assigned to rcw. var runtimeWrapperReference = new System.WeakReference <object>(runtimeWrapper); var cleanupSentinel = new RuntimeWrapperCleanup(identity.ThisPtr, runtimeWrapperReference); return(runtimeWrapperReference); };
internal static bool TryGetMarshalerTypeForProjectedRuntimeClass(IObjectReference objectReference, out Type type) { if (objectReference.TryAs <IInspectable.Vftbl>(out var inspectablePtr) == 0) { rwlock.EnterReadLock(); try { IInspectable inspectable = inspectablePtr; string runtimeClassName = inspectable.GetRuntimeClassName(true); if (runtimeClassName is object) { if (ProjectedRuntimeClassNames.Contains(runtimeClassName)) { type = CustomTypeToHelperTypeMappings[CustomAbiTypeNameToTypeMappings[runtimeClassName]]; return(true); } } } finally { inspectablePtr.Dispose(); rwlock.ExitReadLock(); } } type = null; return(false); }
private static Exception GetExceptionForHR(int hr, bool useGlobalErrorState, out bool restoredExceptionFromGlobalState) { restoredExceptionFromGlobalState = false; if (hr >= 0) { return(null); } ObjectReference <ABI.WinRT.Interop.IErrorInfo.Vftbl> iErrorInfo = null; IObjectReference restrictedErrorInfoToSave = null; Exception ex; string description = null; string restrictedError = null; string restrictedErrorReference = null; string restrictedCapabilitySid = null; bool hasOtherLanguageException = false; if (useGlobalErrorState && getRestrictedErrorInfo != null) { Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(out IntPtr restrictedErrorInfoPtr)); if (restrictedErrorInfoPtr != IntPtr.Zero) { IObjectReference restrictedErrorInfoRef = ObjectReference <ABI.WinRT.Interop.IRestrictedErrorInfo.Vftbl> .Attach(ref restrictedErrorInfoPtr); restrictedErrorInfoToSave = restrictedErrorInfoRef.As <ABI.WinRT.Interop.IRestrictedErrorInfo.Vftbl>(); ABI.WinRT.Interop.IRestrictedErrorInfo restrictedErrorInfo = new ABI.WinRT.Interop.IRestrictedErrorInfo(restrictedErrorInfoRef); restrictedErrorInfo.GetErrorDetails(out description, out int hrLocal, out restrictedError, out restrictedCapabilitySid); restrictedErrorReference = restrictedErrorInfo.GetReference(); if (restrictedErrorInfoRef.TryAs <ABI.WinRT.Interop.ILanguageExceptionErrorInfo.Vftbl>(out var languageErrorInfoRef) >= 0) { ILanguageExceptionErrorInfo languageErrorInfo = new ABI.WinRT.Interop.ILanguageExceptionErrorInfo(languageErrorInfoRef); using IObjectReference languageException = languageErrorInfo.GetLanguageException(); if (languageException is object) { if (languageException.IsReferenceToManagedObject) { ex = ComWrappersSupport.FindObject <Exception>(languageException.ThisPtr); if (GetHRForException(ex) == hr) { restoredExceptionFromGlobalState = true; return(ex); } } else { hasOtherLanguageException = true; } } } else { if (hr == hrLocal) { restrictedErrorInfoRef.TryAs <ABI.WinRT.Interop.IErrorInfo.Vftbl>(out iErrorInfo); } } } }
private static bool TryGetComposedRefForQI(object value, out IObjectReference objRef) { var getReferenceMethod = value.GetType().GetMethod("GetDefaultReference", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(typeof(IUnknownVftbl)); if (getReferenceMethod is null) { objRef = null; return(false); } objRef = (IObjectReference)getReferenceMethod.Invoke(value, Array.Empty <object>()); return(true); }
private static bool TryGetRefForObject(object value, bool allowComposed, out IObjectReference reference) { if (ComWrappersSupport.TryUnwrapObject(value, out var objRef)) { reference = objRef.As <IUnknownVftbl>(); return(true); } else if (allowComposed && TryGetComposedRefForQI(value, out objRef)) { reference = objRef.As <IUnknownVftbl>(); return(true); } reference = null; return(false); }
protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags) { IObjectReference objRef = ComWrappersSupport.GetObjectReferenceForInterface(externalComObject); if (objRef.TryAs <IInspectable.Vftbl>(out var inspectableRef) == 0) { IInspectable inspectable = new IInspectable(inspectableRef); string runtimeClassName = inspectable.GetRuntimeClassName(noThrow: true); return(runtimeClassName switch { "Windows.Data.Text.WordSegment" => new MS.Internal.WindowsRuntime.Windows.Data.Text.WordSegment(new MS.Internal.WindowsRuntime.ABI.Windows.Data.Text.IWordSegment(objRef)), _ => inspectable });
public SingleInterfaceOptimizedObject(Type type, IObjectReference objRef) { _type = type; Type helperType = type.FindHelperType(); var vftblType = helperType.FindVftblType(); if (vftblType is null) { _obj = objRef.As <IUnknownVftbl>(GuidGenerator.GetIID(helperType)); } else { _obj = (IObjectReference)typeof(IObjectReference).GetMethod("As", Type.EmptyTypes).MakeGenericMethod(vftblType).Invoke(objRef, null); } }
public SingleInterfaceOptimizedObject(Type type, IObjectReference objRef) { this._type = type; Type helperType = type.FindHelperType(); var vftblType = helperType.GetNestedType("Vftbl"); if (vftblType is null) { // The helper type might not have a vftbl type if it was linked away. // The only time the Vftbl type would be linked away is when we don't actually use // any of the methods on the interface (it was just a type cast/"is Type" check). // In that case, we can use the IUnknownVftbl-typed ObjectReference since // it has all of the information we'll need. _obj = objRef; } if (vftblType.IsGenericTypeDefinition) { vftblType = vftblType.MakeGenericType(type.GetGenericArguments()); } this._obj = (IObjectReference)typeof(IObjectReference).GetMethod("As", Type.EmptyTypes).MakeGenericMethod(vftblType).Invoke(objRef, null); }
internal EventSource(IObjectReference obj, _add_EventHandler addHandler, _remove_EventHandler removeHandler) { _obj = obj; _addHandler = addHandler; _removeHandler = removeHandler; }
protected virtual void DisposeMarshaler(IObjectReference marshaler) { Marshaler <TDelegate> .DisposeMarshaler(marshaler); }
protected virtual IntPtr GetAbi(IObjectReference marshaler) { return((IntPtr)Marshaler <TDelegate> .GetAbi(marshaler)); }