diff --git a/src/WinRT.Runtime2/InteropServices/Activation/WindowsRuntimeActivationHelper.cs b/src/WinRT.Runtime2/InteropServices/Activation/WindowsRuntimeActivationHelper.cs
index c16f258c0..cccb36366 100644
--- a/src/WinRT.Runtime2/InteropServices/Activation/WindowsRuntimeActivationHelper.cs
+++ b/src/WinRT.Runtime2/InteropServices/Activation/WindowsRuntimeActivationHelper.cs
@@ -20,7 +20,7 @@ internal static unsafe class WindowsRuntimeActivationHelper
/// Activates a new Windows Runtime sealed instance.
///
/// The for the IActivationFactory instance.
- /// The resulting default interface pointer.
+ /// The resulting IInspectable interface pointer.
/// Thrown if activating the instance fails.
///
/// This shared factory helper can be used to activate Windows Runtime sealed types that have a parameterless constructor.
@@ -28,20 +28,59 @@ internal static unsafe class WindowsRuntimeActivationHelper
///
///
[MethodImpl(MethodImplOptions.NoInlining)]
- public static void ActivateInstanceUnsafe(WindowsRuntimeObjectReference activationFactoryObjectReference, out void* defaultInterface)
+ public static void ActivateInstanceUnsafe(WindowsRuntimeObjectReference activationFactoryObjectReference, out void* inspectableInterface)
{
using WindowsRuntimeObjectReferenceValue activationFactoryValue = activationFactoryObjectReference.AsValue();
- fixed (void** defaultInterfacePtr = &defaultInterface)
+ fixed (void** inspectableInterfacePtr = &inspectableInterface)
{
HRESULT hresult = IActivationFactoryVftbl.ActivateInstanceUnsafe(
thisPtr: activationFactoryValue.GetThisPtrUnsafe(),
- instance: defaultInterfacePtr);
+ instance: inspectableInterfacePtr);
RestrictedErrorInfo.ThrowExceptionForHR(hresult);
}
}
+ /// The IID of the default interface pointer (from the activation factory) to return.
+ /// The resulting default interface pointer.
+ ///
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void ActivateInstanceUnsafe(
+ WindowsRuntimeObjectReference activationFactoryObjectReference,
+ in Guid iid,
+ out void* defaultInterface)
+ {
+ void* inspectableInterface;
+
+ // Get the 'IInspectable' object from the activation factory (same as above)
+ using (WindowsRuntimeObjectReferenceValue activationFactoryValue = activationFactoryObjectReference.AsValue())
+ {
+ HRESULT hresult = IActivationFactoryVftbl.ActivateInstanceUnsafe(
+ thisPtr: activationFactoryValue.GetThisPtrUnsafe(),
+ instance: &inspectableInterface);
+
+ RestrictedErrorInfo.ThrowExceptionForHR(hresult);
+ }
+
+ // Query the 'IInspectable' object for the default interface, which is what callers expect.
+ // We only need this when using the parameterless constructor, since in this case we must
+ // go through 'IActivationFactory', which only declares 'IInspectable' as the return type
+ // for 'CreateInstance'. For other constructors instead, those would be declared on each
+ // specialized factory type, and would return the default interface directly.
+ try
+ {
+ fixed (void** defaultInterfacePtr = &defaultInterface)
+ {
+ IUnknownVftbl.QueryInterfaceUnsafe(inspectableInterface, in iid, out defaultInterface).Assert();
+ }
+ }
+ finally
+ {
+ _ = IUnknownVftbl.ReleaseUnsafe(inspectableInterface);
+ }
+ }
+
///
/// Activates a new Windows Runtime instance.
///
diff --git a/src/WinRT.Runtime2/WindowsRuntimeObject.cs b/src/WinRT.Runtime2/WindowsRuntimeObject.cs
index 0f634f2ac..208550833 100644
--- a/src/WinRT.Runtime2/WindowsRuntimeObject.cs
+++ b/src/WinRT.Runtime2/WindowsRuntimeObject.cs
@@ -90,6 +90,7 @@ protected WindowsRuntimeObject(
// See additional notes in the overload below for more details about how and when that parameter is necessary.
WindowsRuntimeActivationHelper.ActivateInstanceUnsafe(
activationFactoryObjectReference: activationFactoryObjectReference,
+ iid: in iid,
defaultInterface: out void* defaultInterface);
// The inner interface pointer isn't used for non-composable types, so we just pass 'null'