diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index 660665c3046e5..8538e63c06880 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -10,66 +10,6 @@ namespace System.Runtime.InteropServices { - /// - /// Enumeration of flags for . - /// - [Flags] - public enum CreateComInterfaceFlags - { - None = 0, - - /// - /// The caller will provide an IUnknown Vtable. - /// - /// - /// This is useful in scenarios when the caller has no need to rely on an IUnknown instance - /// that is used when running managed code is not possible (i.e. during a GC). In traditional - /// COM scenarios this is common, but scenarios involving Reference Tracker hosting - /// calling of the IUnknown API during a GC is possible. - /// - CallerDefinedIUnknown = 1, - - /// - /// Flag used to indicate the COM interface should implement IReferenceTrackerTarget. - /// When this flag is passed, the resulting COM interface will have an internal implementation of IUnknown - /// and as such none should be supplied by the caller. - /// - TrackerSupport = 2, - } - - /// - /// Enumeration of flags for . - /// - [Flags] - public enum CreateObjectFlags - { - None = 0, - - /// - /// Indicate if the supplied external COM object implements the IReferenceTracker. - /// - TrackerObject = 1, - - /// - /// Ignore any internal caching and always create a unique instance. - /// - UniqueInstance = 2, - - /// - /// Defined when COM aggregation is involved (that is an inner instance supplied). - /// - Aggregation = 4, - - /// - /// Check if the supplied instance is actually a wrapper and if so return the underlying - /// managed object rather than creating a new wrapper. - /// - /// - /// This matches the built-in RCW semantics for COM interop. - /// - Unwrap = 8, - } - /// /// Internal enumeration used by the runtime to indicate the scenario for which ComWrappers is being used. /// @@ -83,33 +23,13 @@ internal enum ComWrappersScenario /// /// Class for managing wrappers of COM IUnknown types. /// - [SupportedOSPlatform("windows")] - [CLSCompliant(false)] public abstract partial class ComWrappers { - /// - /// Interface type and pointer to targeted VTable. - /// - public struct ComInterfaceEntry - { - /// - /// Interface IID. - /// - public Guid IID; - - /// - /// Memory must have the same lifetime as the memory returned from the call to . - /// - public IntPtr Vtable; - } - /// /// ABI for function dispatch of a COM interface. /// - public struct ComInterfaceDispatch + public partial struct ComInterfaceDispatch { - public IntPtr Vtable; - /// /// Given a from a generated Vtable, convert to the target type. /// @@ -186,22 +106,6 @@ private static bool TryGetOrCreateComInterfaceForObjectInternal(ComWrappers impl [DllImport(RuntimeHelpers.QCall)] private static extern bool TryGetOrCreateComInterfaceForObjectInternal(ObjectHandleOnStack comWrappersImpl, long wrapperId, ObjectHandleOnStack instance, CreateComInterfaceFlags flags, out IntPtr retValue); - /// - /// Compute the desired Vtable for respecting the values of . - /// - /// Target of the returned Vtables. - /// Flags used to compute Vtables. - /// The number of elements contained in the returned memory. - /// pointer containing memory for all COM interface entries. - /// - /// All memory returned from this function must either be unmanaged memory, pinned managed memory, or have been - /// allocated with the API. - /// - /// If the interface entries cannot be created and a negative or null and a non-zero are returned, - /// the call to will throw a . - /// - protected unsafe abstract ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count); - // Called by the runtime to execute the abstract instance function internal static unsafe void* CallComputeVtables(ComWrappersScenario scenario, ComWrappers? comWrappersImpl, object obj, CreateComInterfaceFlags flags, out int count) { @@ -248,17 +152,6 @@ public object GetOrCreateObjectForComInstance(IntPtr externalComObject, CreateOb return obj!; } - /// - /// Create a managed object for the object pointed at by respecting the values of . - /// - /// Object to import for usage into the .NET runtime. - /// Flags used to describe the external object. - /// Returns a managed object associated with the supplied external COM object. - /// - /// If the object cannot be created and null is returned, the call to will throw a . - /// - protected abstract object? CreateObject(IntPtr externalComObject, CreateObjectFlags flags); - // Called by the runtime to execute the abstract instance function. internal static object? CallCreateObject(ComWrappersScenario scenario, ComWrappers? comWrappersImpl, IntPtr externalComObject, CreateObjectFlags flags) { @@ -361,12 +254,6 @@ private static bool TryGetOrCreateObjectForComInstanceInternal( [DllImport(RuntimeHelpers.QCall)] private static extern bool TryGetOrCreateObjectForComInstanceInternal(ObjectHandleOnStack comWrappersImpl, long wrapperId, IntPtr externalComObject, IntPtr innerMaybe, CreateObjectFlags flags, ObjectHandleOnStack wrapper, ObjectHandleOnStack retValue); - /// - /// Called when a request is made for a collection of objects to be released outside of normal object or COM interface lifetime. - /// - /// Collection of objects to release. - protected abstract void ReleaseObjects(IEnumerable objects); - // Call to execute the virtual instance function internal static void CallReleaseObjects(ComWrappers? comWrappersImpl, IEnumerable objects) => (comWrappersImpl ?? s_globalInstanceForTrackerSupport!).ReleaseObjects(objects); diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index fd5b33c24c7b1..69842a262f148 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -745,6 +745,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs index 9dc7e1789ebad..2cfac1e1919e9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs @@ -6,38 +6,10 @@ namespace System.Runtime.InteropServices { - [Flags] - public enum CreateComInterfaceFlags + public abstract partial class ComWrappers { - None = 0, - CallerDefinedIUnknown = 1, - TrackerSupport = 2, - } - - [Flags] - public enum CreateObjectFlags - { - None = 0, - TrackerObject = 1, - UniqueInstance = 2, - Aggregation = 4, - Unwrap = 8, - } - - [SupportedOSPlatform("windows")] - [CLSCompliant(false)] - public abstract class ComWrappers - { - public struct ComInterfaceEntry + public partial struct ComInterfaceDispatch { - public Guid IID; - public IntPtr Vtable; - } - - public struct ComInterfaceDispatch - { - public IntPtr Vtable; - public static unsafe T GetInstance(ComInterfaceDispatch* dispatchPtr) where T : class { throw new PlatformNotSupportedException(); @@ -49,15 +21,11 @@ public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfa throw new PlatformNotSupportedException(); } - protected abstract unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count); - public object GetOrCreateObjectForComInstance(IntPtr externalComObject, CreateObjectFlags flags) { throw new PlatformNotSupportedException(); } - protected abstract object? CreateObject(IntPtr externalComObject, CreateObjectFlags flags); - public object GetOrRegisterObjectForComInstance(IntPtr externalComObject, CreateObjectFlags flags, object wrapper) { throw new PlatformNotSupportedException(); @@ -68,8 +36,6 @@ public object GetOrRegisterObjectForComInstance(IntPtr externalComObject, Create throw new PlatformNotSupportedException(); } - protected abstract void ReleaseObjects(IEnumerable objects); - public static void RegisterForTrackerSupport(ComWrappers instance) { throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs new file mode 100644 index 0000000000000..72019f3d833cc --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections; +using System.Runtime.Versioning; + +namespace System.Runtime.InteropServices +{ + /// + /// Enumeration of flags for . + /// + [Flags] + public enum CreateComInterfaceFlags + { + None = 0, + + /// + /// The caller will provide an IUnknown Vtable. + /// + /// + /// This is useful in scenarios when the caller has no need to rely on an IUnknown instance + /// that is used when running managed code is not possible (i.e. during a GC). In traditional + /// COM scenarios this is common, but scenarios involving Reference Tracker hosting + /// calling of the IUnknown API during a GC is possible. + /// + CallerDefinedIUnknown = 1, + + /// + /// Flag used to indicate the COM interface should implement IReferenceTrackerTarget. + /// When this flag is passed, the resulting COM interface will have an internal implementation of IUnknown + /// and as such none should be supplied by the caller. + /// + TrackerSupport = 2, + } + + /// + /// Enumeration of flags for . + /// + [Flags] + public enum CreateObjectFlags + { + None = 0, + + /// + /// Indicate if the supplied external COM object implements the IReferenceTracker. + /// + TrackerObject = 1, + + /// + /// Ignore any internal caching and always create a unique instance. + /// + UniqueInstance = 2, + + /// + /// Defined when COM aggregation is involved (that is an inner instance supplied). + /// + Aggregation = 4, + + /// + /// Check if the supplied instance is actually a wrapper and if so return the underlying + /// managed object rather than creating a new wrapper. + /// + /// + /// This matches the built-in RCW semantics for COM interop. + /// + Unwrap = 8, + } + + /// + /// Class for managing wrappers of COM IUnknown types. + /// + [SupportedOSPlatform("windows")] + [CLSCompliant(false)] + public abstract partial class ComWrappers + { + /// + /// Interface type and pointer to targeted VTable. + /// + public struct ComInterfaceEntry + { + /// + /// Interface IID. + /// + public Guid IID; + + /// + /// Memory must have the same lifetime as the memory returned from the call to . + /// + public IntPtr Vtable; + } + /// + /// ABI for function dispatch of a COM interface. + /// + public partial struct ComInterfaceDispatch + { + public IntPtr Vtable; + } + + /// + /// Compute the desired Vtable for respecting the values of . + /// + /// Target of the returned Vtables. + /// Flags used to compute Vtables. + /// The number of elements contained in the returned memory. + /// pointer containing memory for all COM interface entries. + /// + /// All memory returned from this function must either be unmanaged memory, pinned managed memory, or have been + /// allocated with the API. + /// + /// If the interface entries cannot be created and a negative or null and a non-zero are returned, + /// the call to will throw a . + /// + protected unsafe abstract ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count); + + /// + /// Create a managed object for the object pointed at by respecting the values of . + /// + /// Object to import for usage into the .NET runtime. + /// Flags used to describe the external object. + /// Returns a managed object associated with the supplied external COM object. + /// + /// If the object cannot be created and null is returned, the call to will throw a . + /// + protected abstract object? CreateObject(IntPtr externalComObject, CreateObjectFlags flags); + + /// + /// Called when a request is made for a collection of objects to be released outside of normal object or COM interface lifetime. + /// + /// Collection of objects to release. + protected abstract void ReleaseObjects(IEnumerable objects); + } +}