Skip to content

Feature switch to turn off COM support in Windows #50662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,16 @@ public struct ComActivationContext
public string AssemblyName;
public string TypeName;

[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
[CLSCompliant(false)]
public static unsafe ComActivationContext Create(ref ComActivationContextInternal cxtInt)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return new ComActivationContext()
{
ClassId = cxtInt.ClassId,
Expand Down Expand Up @@ -122,9 +128,15 @@ public static class ComActivator
/// Entry point for unmanaged COM activation API from managed code
/// </summary>
/// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
public static object GetClassFactoryForType(ComActivationContext cxt)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

if (cxt.InterfaceId != typeof(IClassFactory).GUID
&& cxt.InterfaceId != typeof(IClassFactory2).GUID)
{
Expand Down Expand Up @@ -154,9 +166,15 @@ public static object GetClassFactoryForType(ComActivationContext cxt)
/// </summary>
/// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
/// <param name="register">true if called for register or false to indicate unregister</param>
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bool register)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

// Retrieve the attribute type to use to determine if a function is the requested user defined
// registration function.
string attributeName = register ? "ComRegisterFunctionAttribute" : "ComUnregisterFunctionAttribute";
Expand Down Expand Up @@ -246,11 +264,17 @@ public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bo
/// Internal entry point for unmanaged COM activation API from native code
/// </summary>
/// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
[CLSCompliant(false)]
[UnmanagedCallersOnly]
public static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInternal* pCxtInt)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

ref ComActivationContextInternal cxtInt = ref *pCxtInt;

if (IsLoggingEnabled())
Expand Down Expand Up @@ -287,11 +311,17 @@ public static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInte
/// Internal entry point for registering a managed COM server API from native code
/// </summary>
/// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
[CLSCompliant(false)]
[UnmanagedCallersOnly]
public static unsafe int RegisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

ref ComActivationContextInternal cxtInt = ref *pCxtInt;

if (IsLoggingEnabled())
Expand Down Expand Up @@ -331,11 +361,17 @@ public static unsafe int RegisterClassForTypeInternal(ComActivationContextIntern
/// <summary>
/// Internal entry point for unregistering a managed COM server API from native code
/// </summary>
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
[CLSCompliant(false)]
[UnmanagedCallersOnly]
public static unsafe int UnregisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

ref ComActivationContextInternal cxtInt = ref *pCxtInt;

if (IsLoggingEnabled())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ private static void PrelinkCore(MethodInfo m)
[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void InternalPrelink(RuntimeMethodHandleInternal m);

[DllImport(RuntimeHelpers.QCall)]
private static extern bool IsComSupportedInternal();

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern /* struct _EXCEPTION_POINTERS* */ IntPtr GetExceptionPointers();

Expand Down Expand Up @@ -221,6 +224,10 @@ private static object PtrToStructureHelper(IntPtr ptr, Type structureType)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool IsPinnable(object? obj);

internal static bool IsComSupported { get; } = InitializeIsComSupported();

private static bool InitializeIsComSupported() => IsComSupportedInternal();

#if TARGET_WINDOWS
/// <summary>
/// Returns the HInstance for this module. Returns -1 if the module doesn't have
Expand Down Expand Up @@ -277,6 +284,11 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
// on Marshal for more consistent API surface.
internal static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

// Note: "throwOnError" is a vacuous parameter. Any errors due to the CLSID not being registered or the server not being found will happen
// on the Activator.CreateInstance() call. GetTypeFromCLSID() merely wraps the data in a Type object without any validation.

Expand Down Expand Up @@ -417,12 +429,27 @@ public static object GetUniqueObjectForIUnknown(IntPtr unknown)
public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t);

[SupportedOSPlatform("windows")]
public static IntPtr CreateAggregatedObject(IntPtr pOuter, object o)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return CreateAggregatedObjectNative(pOuter, o);
}

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o);
private static extern IntPtr CreateAggregatedObjectNative(IntPtr pOuter, object o);

[SupportedOSPlatform("windows")]
public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o) where T : notnull
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return CreateAggregatedObject(pOuter, (object)o);
}

Expand All @@ -445,6 +472,11 @@ public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o) where T : not
[SupportedOSPlatform("windows")]
public static int ReleaseComObject(object o)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

if (o is null)
{
// Match .NET Framework behaviour.
Expand All @@ -468,6 +500,11 @@ public static int ReleaseComObject(object o)
[SupportedOSPlatform("windows")]
public static int FinalReleaseComObject(object o)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

if (o is null)
{
throw new ArgumentNullException(nameof(o));
Expand All @@ -487,6 +524,11 @@ public static int FinalReleaseComObject(object o)
[SupportedOSPlatform("windows")]
public static object? GetComObjectData(object obj, object key)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
Expand All @@ -513,6 +555,11 @@ public static int FinalReleaseComObject(object o)
[SupportedOSPlatform("windows")]
public static bool SetComObjectData(object obj, object key, object? data)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
Expand All @@ -538,6 +585,11 @@ public static bool SetComObjectData(object obj, object key, object? data)
[return: NotNullIfNotNull("o")]
public static object? CreateWrapperOfType(object? o, Type t)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

if (t is null)
{
throw new ArgumentNullException(nameof(t));
Expand Down Expand Up @@ -588,6 +640,11 @@ public static bool SetComObjectData(object obj, object key, object? data)
[SupportedOSPlatform("windows")]
public static TWrapper CreateWrapperOfType<T, TWrapper>(T? o)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!;
}

Expand All @@ -601,32 +658,77 @@ public static TWrapper CreateWrapperOfType<T, TWrapper>(T? o)
public static extern bool IsTypeVisibleFromCom(Type t);

[SupportedOSPlatform("windows")]
public static void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

GetNativeVariantForObjectNative(obj, pDstNativeVariant);
}

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant);
private static extern void GetNativeVariantForObjectNative(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant);

[SupportedOSPlatform("windows")]
public static void GetNativeVariantForObject<T>(T? obj, IntPtr pDstNativeVariant)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

GetNativeVariantForObject((object?)obj, pDstNativeVariant);
}

[SupportedOSPlatform("windows")]
public static object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return GetObjectForNativeVariantNative(pSrcNativeVariant);
}

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant);
private static extern object? GetObjectForNativeVariantNative(/* VARIANT * */ IntPtr pSrcNativeVariant);

[SupportedOSPlatform("windows")]
public static T? GetObjectForNativeVariant<T>(IntPtr pSrcNativeVariant)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return (T?)GetObjectForNativeVariant(pSrcNativeVariant);
}

[SupportedOSPlatform("windows")]
public static object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

return GetObjectsForNativeVariantsNative(aSrcNativeVariant, cVars);
}

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);
private static extern object?[] GetObjectsForNativeVariantsNative(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);

[SupportedOSPlatform("windows")]
public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int cVars)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

object?[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);

T[] result = new T[objects.Length];
Expand All @@ -653,6 +755,11 @@ public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int c
[SupportedOSPlatform("windows")]
public static object BindToMoniker(string monikerName)
{
if (!IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

CreateBindCtx(0, out IBindCtx bindctx);

MkParseDisplayName(bindctx, monikerName, out _, out IMoniker pmoniker);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3680,6 +3680,11 @@ private extern object InvokeDispMethod(
Type[] aArgsTypes,
Type retType)
{
if (!Marshal.IsComSupported)
{
throw new NotSupportedException(SR.NotSupported_COM);
}

Debug.Assert(
aArgs.Length == aArgsIsByRef.Length
&& aArgs.Length == aArgsTypes.Length
Expand Down
9 changes: 5 additions & 4 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("OffsetOfHelper", MarshalNative::OffsetOfHelper)

QCFuncElement("InternalPrelink", MarshalNative::Prelink)
QCFuncElement("IsComSupportedInternal", MarshalNative::IsComSupported)
FCFuncElement("GetExceptionForHRInternal", MarshalNative::GetExceptionForHR)
FCFuncElement("GetDelegateForFunctionPointerInternal", MarshalNative::GetDelegateForFunctionPointerInternal)
FCFuncElement("GetFunctionPointerForDelegateInternal", MarshalNative::GetFunctionPointerForDelegateInternal)
Expand All @@ -767,14 +768,14 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("IsComObject", MarshalNative::IsComObject)
FCFuncElement("GetObjectForIUnknownNative", MarshalNative::GetObjectForIUnknownNative)
FCFuncElement("GetUniqueObjectForIUnknownNative", MarshalNative::GetUniqueObjectForIUnknownNative)
FCFuncElement("GetNativeVariantForObject", MarshalNative::GetNativeVariantForObject)
FCFuncElement("GetObjectForNativeVariant", MarshalNative::GetObjectForNativeVariant)
FCFuncElement("GetNativeVariantForObjectNative", MarshalNative::GetNativeVariantForObjectNative)
FCFuncElement("GetObjectForNativeVariantNative", MarshalNative::GetObjectForNativeVariantNative)
FCFuncElement("InternalFinalReleaseComObject", MarshalNative::FinalReleaseComObject)
FCFuncElement("IsTypeVisibleFromCom", MarshalNative::IsTypeVisibleFromCom)
FCFuncElement("CreateAggregatedObject", MarshalNative::CreateAggregatedObject)
FCFuncElement("CreateAggregatedObjectNative", MarshalNative::CreateAggregatedObjectNative)
FCFuncElement("AreComObjectsAvailableForCleanup", MarshalNative::AreComObjectsAvailableForCleanup)
FCFuncElement("InternalCreateWrapperOfType", MarshalNative::InternalCreateWrapperOfType)
FCFuncElement("GetObjectsForNativeVariants", MarshalNative::GetObjectsForNativeVariants)
FCFuncElement("GetObjectsForNativeVariantsNative", MarshalNative::GetObjectsForNativeVariantsNative)
FCFuncElement("GetStartComSlot", MarshalNative::GetStartComSlot)
FCFuncElement("GetEndComSlot", MarshalNative::GetEndComSlot)
FCFuncElement("GetIUnknownForObjectNative", MarshalNative::GetIUnknownForObjectNative)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/eeconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ HRESULT EEConfig::Init()
#ifdef FEATURE_COMINTEROP
bLogCCWRefCountChange = false;
pszLogCCWRefCountChange = NULL;
m_fBuiltInCOMInteropSupported = true;
#endif // FEATURE_COMINTEROP

#ifdef _DEBUG
Expand Down Expand Up @@ -682,6 +683,7 @@ HRESULT EEConfig::sync()
bLogCCWRefCountChange = true;

fEnableRCWCleanupOnSTAShutdown = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EnableRCWCleanupOnSTAShutdown) != 0);
m_fBuiltInCOMInteropSupported = Configuration::GetKnobBooleanValue(W("System.Runtime.InteropServices.Marshal.IsComSupported"), true);
#endif // FEATURE_COMINTEROP

#ifdef _DEBUG
Expand Down
Loading