Skip to content

Commit 1c9e200

Browse files
authored
Feature switch to turn off COM support in Windows (#50662)
* Incorporating FB * non-windows build break fix * FB * fb * test fixes + added new guards to missed ones * test fixed based on FB
1 parent 9a31832 commit 1c9e200

File tree

12 files changed

+400
-16
lines changed

12 files changed

+400
-16
lines changed

src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,16 @@ public struct ComActivationContext
9191
public string AssemblyName;
9292
public string TypeName;
9393

94+
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
9495
[CLSCompliant(false)]
9596
public static unsafe ComActivationContext Create(ref ComActivationContextInternal cxtInt)
9697
{
9798
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
99+
if (!Marshal.IsComSupported)
100+
{
101+
throw new NotSupportedException(SR.NotSupported_COM);
102+
}
103+
98104
return new ComActivationContext()
99105
{
100106
ClassId = cxtInt.ClassId,
@@ -122,9 +128,15 @@ public static class ComActivator
122128
/// Entry point for unmanaged COM activation API from managed code
123129
/// </summary>
124130
/// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
131+
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
125132
public static object GetClassFactoryForType(ComActivationContext cxt)
126133
{
127134
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
135+
if (!Marshal.IsComSupported)
136+
{
137+
throw new NotSupportedException(SR.NotSupported_COM);
138+
}
139+
128140
if (cxt.InterfaceId != typeof(IClassFactory).GUID
129141
&& cxt.InterfaceId != typeof(IClassFactory2).GUID)
130142
{
@@ -154,9 +166,15 @@ public static object GetClassFactoryForType(ComActivationContext cxt)
154166
/// </summary>
155167
/// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
156168
/// <param name="register">true if called for register or false to indicate unregister</param>
169+
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
157170
public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bool register)
158171
{
159172
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
173+
if (!Marshal.IsComSupported)
174+
{
175+
throw new NotSupportedException(SR.NotSupported_COM);
176+
}
177+
160178
// Retrieve the attribute type to use to determine if a function is the requested user defined
161179
// registration function.
162180
string attributeName = register ? "ComRegisterFunctionAttribute" : "ComUnregisterFunctionAttribute";
@@ -246,11 +264,17 @@ public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bo
246264
/// Internal entry point for unmanaged COM activation API from native code
247265
/// </summary>
248266
/// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
267+
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
249268
[CLSCompliant(false)]
250269
[UnmanagedCallersOnly]
251270
public static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInternal* pCxtInt)
252271
{
253272
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
273+
if (!Marshal.IsComSupported)
274+
{
275+
throw new NotSupportedException(SR.NotSupported_COM);
276+
}
277+
254278
ref ComActivationContextInternal cxtInt = ref *pCxtInt;
255279

256280
if (IsLoggingEnabled())
@@ -287,11 +311,17 @@ public static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInte
287311
/// Internal entry point for registering a managed COM server API from native code
288312
/// </summary>
289313
/// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
314+
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
290315
[CLSCompliant(false)]
291316
[UnmanagedCallersOnly]
292317
public static unsafe int RegisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
293318
{
294319
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
320+
if (!Marshal.IsComSupported)
321+
{
322+
throw new NotSupportedException(SR.NotSupported_COM);
323+
}
324+
295325
ref ComActivationContextInternal cxtInt = ref *pCxtInt;
296326

297327
if (IsLoggingEnabled())
@@ -331,11 +361,17 @@ public static unsafe int RegisterClassForTypeInternal(ComActivationContextIntern
331361
/// <summary>
332362
/// Internal entry point for unregistering a managed COM server API from native code
333363
/// </summary>
364+
[RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
334365
[CLSCompliant(false)]
335366
[UnmanagedCallersOnly]
336367
public static unsafe int UnregisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
337368
{
338369
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
370+
if (!Marshal.IsComSupported)
371+
{
372+
throw new NotSupportedException(SR.NotSupported_COM);
373+
}
374+
339375
ref ComActivationContextInternal cxtInt = ref *pCxtInt;
340376

341377
if (IsLoggingEnabled())

src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ private static void PrelinkCore(MethodInfo m)
195195
[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
196196
private static extern void InternalPrelink(RuntimeMethodHandleInternal m);
197197

198+
[DllImport(RuntimeHelpers.QCall)]
199+
private static extern bool IsComSupportedInternal();
200+
198201
[MethodImpl(MethodImplOptions.InternalCall)]
199202
public static extern /* struct _EXCEPTION_POINTERS* */ IntPtr GetExceptionPointers();
200203

@@ -233,6 +236,10 @@ private static object PtrToStructureHelper(IntPtr ptr, Type structureType)
233236
[MethodImpl(MethodImplOptions.InternalCall)]
234237
internal static extern bool IsPinnable(object? obj);
235238

239+
internal static bool IsComSupported { get; } = InitializeIsComSupported();
240+
241+
private static bool InitializeIsComSupported() => IsComSupportedInternal();
242+
236243
#if TARGET_WINDOWS
237244
/// <summary>
238245
/// Returns the HInstance for this module. Returns -1 if the module doesn't have
@@ -289,6 +296,11 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
289296
// on Marshal for more consistent API surface.
290297
internal static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError)
291298
{
299+
if (!IsComSupported)
300+
{
301+
throw new NotSupportedException(SR.NotSupported_COM);
302+
}
303+
292304
// Note: "throwOnError" is a vacuous parameter. Any errors due to the CLSID not being registered or the server not being found will happen
293305
// on the Activator.CreateInstance() call. GetTypeFromCLSID() merely wraps the data in a Type object without any validation.
294306

@@ -429,12 +441,27 @@ public static object GetUniqueObjectForIUnknown(IntPtr unknown)
429441
public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t);
430442

431443
[SupportedOSPlatform("windows")]
444+
public static IntPtr CreateAggregatedObject(IntPtr pOuter, object o)
445+
{
446+
if (!IsComSupported)
447+
{
448+
throw new NotSupportedException(SR.NotSupported_COM);
449+
}
450+
451+
return CreateAggregatedObjectNative(pOuter, o);
452+
}
453+
432454
[MethodImpl(MethodImplOptions.InternalCall)]
433-
public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o);
455+
private static extern IntPtr CreateAggregatedObjectNative(IntPtr pOuter, object o);
434456

435457
[SupportedOSPlatform("windows")]
436458
public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o) where T : notnull
437459
{
460+
if (!IsComSupported)
461+
{
462+
throw new NotSupportedException(SR.NotSupported_COM);
463+
}
464+
438465
return CreateAggregatedObject(pOuter, (object)o);
439466
}
440467

@@ -457,6 +484,11 @@ public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o) where T : not
457484
[SupportedOSPlatform("windows")]
458485
public static int ReleaseComObject(object o)
459486
{
487+
if (!IsComSupported)
488+
{
489+
throw new NotSupportedException(SR.NotSupported_COM);
490+
}
491+
460492
if (o is null)
461493
{
462494
// Match .NET Framework behaviour.
@@ -480,6 +512,11 @@ public static int ReleaseComObject(object o)
480512
[SupportedOSPlatform("windows")]
481513
public static int FinalReleaseComObject(object o)
482514
{
515+
if (!IsComSupported)
516+
{
517+
throw new NotSupportedException(SR.NotSupported_COM);
518+
}
519+
483520
if (o is null)
484521
{
485522
throw new ArgumentNullException(nameof(o));
@@ -499,6 +536,11 @@ public static int FinalReleaseComObject(object o)
499536
[SupportedOSPlatform("windows")]
500537
public static object? GetComObjectData(object obj, object key)
501538
{
539+
if (!IsComSupported)
540+
{
541+
throw new NotSupportedException(SR.NotSupported_COM);
542+
}
543+
502544
if (obj is null)
503545
{
504546
throw new ArgumentNullException(nameof(obj));
@@ -525,6 +567,11 @@ public static int FinalReleaseComObject(object o)
525567
[SupportedOSPlatform("windows")]
526568
public static bool SetComObjectData(object obj, object key, object? data)
527569
{
570+
if (!IsComSupported)
571+
{
572+
throw new NotSupportedException(SR.NotSupported_COM);
573+
}
574+
528575
if (obj is null)
529576
{
530577
throw new ArgumentNullException(nameof(obj));
@@ -550,6 +597,11 @@ public static bool SetComObjectData(object obj, object key, object? data)
550597
[return: NotNullIfNotNull("o")]
551598
public static object? CreateWrapperOfType(object? o, Type t)
552599
{
600+
if (!IsComSupported)
601+
{
602+
throw new NotSupportedException(SR.NotSupported_COM);
603+
}
604+
553605
if (t is null)
554606
{
555607
throw new ArgumentNullException(nameof(t));
@@ -600,6 +652,11 @@ public static bool SetComObjectData(object obj, object key, object? data)
600652
[SupportedOSPlatform("windows")]
601653
public static TWrapper CreateWrapperOfType<T, TWrapper>(T? o)
602654
{
655+
if (!IsComSupported)
656+
{
657+
throw new NotSupportedException(SR.NotSupported_COM);
658+
}
659+
603660
return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!;
604661
}
605662

@@ -613,32 +670,77 @@ public static TWrapper CreateWrapperOfType<T, TWrapper>(T? o)
613670
public static extern bool IsTypeVisibleFromCom(Type t);
614671

615672
[SupportedOSPlatform("windows")]
673+
public static void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant)
674+
{
675+
if (!IsComSupported)
676+
{
677+
throw new NotSupportedException(SR.NotSupported_COM);
678+
}
679+
680+
GetNativeVariantForObjectNative(obj, pDstNativeVariant);
681+
}
682+
616683
[MethodImpl(MethodImplOptions.InternalCall)]
617-
public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant);
684+
private static extern void GetNativeVariantForObjectNative(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant);
618685

619686
[SupportedOSPlatform("windows")]
620687
public static void GetNativeVariantForObject<T>(T? obj, IntPtr pDstNativeVariant)
621688
{
689+
if (!IsComSupported)
690+
{
691+
throw new NotSupportedException(SR.NotSupported_COM);
692+
}
693+
622694
GetNativeVariantForObject((object?)obj, pDstNativeVariant);
623695
}
624696

625697
[SupportedOSPlatform("windows")]
698+
public static object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant)
699+
{
700+
if (!IsComSupported)
701+
{
702+
throw new NotSupportedException(SR.NotSupported_COM);
703+
}
704+
705+
return GetObjectForNativeVariantNative(pSrcNativeVariant);
706+
}
707+
626708
[MethodImpl(MethodImplOptions.InternalCall)]
627-
public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant);
709+
private static extern object? GetObjectForNativeVariantNative(/* VARIANT * */ IntPtr pSrcNativeVariant);
628710

629711
[SupportedOSPlatform("windows")]
630712
public static T? GetObjectForNativeVariant<T>(IntPtr pSrcNativeVariant)
631713
{
714+
if (!IsComSupported)
715+
{
716+
throw new NotSupportedException(SR.NotSupported_COM);
717+
}
718+
632719
return (T?)GetObjectForNativeVariant(pSrcNativeVariant);
633720
}
634721

635722
[SupportedOSPlatform("windows")]
723+
public static object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars)
724+
{
725+
if (!IsComSupported)
726+
{
727+
throw new NotSupportedException(SR.NotSupported_COM);
728+
}
729+
730+
return GetObjectsForNativeVariantsNative(aSrcNativeVariant, cVars);
731+
}
732+
636733
[MethodImpl(MethodImplOptions.InternalCall)]
637-
public static extern object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);
734+
private static extern object?[] GetObjectsForNativeVariantsNative(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);
638735

639736
[SupportedOSPlatform("windows")]
640737
public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int cVars)
641738
{
739+
if (!IsComSupported)
740+
{
741+
throw new NotSupportedException(SR.NotSupported_COM);
742+
}
743+
642744
object?[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);
643745

644746
T[] result = new T[objects.Length];
@@ -665,6 +767,11 @@ public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int c
665767
[SupportedOSPlatform("windows")]
666768
public static object BindToMoniker(string monikerName)
667769
{
770+
if (!IsComSupported)
771+
{
772+
throw new NotSupportedException(SR.NotSupported_COM);
773+
}
774+
668775
CreateBindCtx(0, out IBindCtx bindctx);
669776

670777
MkParseDisplayName(bindctx, monikerName, out _, out IMoniker pmoniker);

src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3680,6 +3680,11 @@ private extern object InvokeDispMethod(
36803680
Type[] aArgsTypes,
36813681
Type retType)
36823682
{
3683+
if (!Marshal.IsComSupported)
3684+
{
3685+
throw new NotSupportedException(SR.NotSupported_COM);
3686+
}
3687+
36833688
Debug.Assert(
36843689
aArgs.Length == aArgsIsByRef.Length
36853690
&& aArgs.Length == aArgsTypes.Length

src/coreclr/vm/ecalllist.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ FCFuncStart(gInteropMarshalFuncs)
758758
FCFuncElement("OffsetOfHelper", MarshalNative::OffsetOfHelper)
759759

760760
QCFuncElement("InternalPrelink", MarshalNative::Prelink)
761+
QCFuncElement("IsComSupportedInternal", MarshalNative::IsComSupported)
761762
FCFuncElement("GetExceptionForHRInternal", MarshalNative::GetExceptionForHR)
762763
FCFuncElement("GetDelegateForFunctionPointerInternal", MarshalNative::GetDelegateForFunctionPointerInternal)
763764
FCFuncElement("GetFunctionPointerForDelegateInternal", MarshalNative::GetFunctionPointerForDelegateInternal)
@@ -767,14 +768,14 @@ FCFuncStart(gInteropMarshalFuncs)
767768
FCFuncElement("IsComObject", MarshalNative::IsComObject)
768769
FCFuncElement("GetObjectForIUnknownNative", MarshalNative::GetObjectForIUnknownNative)
769770
FCFuncElement("GetUniqueObjectForIUnknownNative", MarshalNative::GetUniqueObjectForIUnknownNative)
770-
FCFuncElement("GetNativeVariantForObject", MarshalNative::GetNativeVariantForObject)
771-
FCFuncElement("GetObjectForNativeVariant", MarshalNative::GetObjectForNativeVariant)
771+
FCFuncElement("GetNativeVariantForObjectNative", MarshalNative::GetNativeVariantForObjectNative)
772+
FCFuncElement("GetObjectForNativeVariantNative", MarshalNative::GetObjectForNativeVariantNative)
772773
FCFuncElement("InternalFinalReleaseComObject", MarshalNative::FinalReleaseComObject)
773774
FCFuncElement("IsTypeVisibleFromCom", MarshalNative::IsTypeVisibleFromCom)
774-
FCFuncElement("CreateAggregatedObject", MarshalNative::CreateAggregatedObject)
775+
FCFuncElement("CreateAggregatedObjectNative", MarshalNative::CreateAggregatedObjectNative)
775776
FCFuncElement("AreComObjectsAvailableForCleanup", MarshalNative::AreComObjectsAvailableForCleanup)
776777
FCFuncElement("InternalCreateWrapperOfType", MarshalNative::InternalCreateWrapperOfType)
777-
FCFuncElement("GetObjectsForNativeVariants", MarshalNative::GetObjectsForNativeVariants)
778+
FCFuncElement("GetObjectsForNativeVariantsNative", MarshalNative::GetObjectsForNativeVariantsNative)
778779
FCFuncElement("GetStartComSlot", MarshalNative::GetStartComSlot)
779780
FCFuncElement("GetEndComSlot", MarshalNative::GetEndComSlot)
780781
FCFuncElement("GetIUnknownForObjectNative", MarshalNative::GetIUnknownForObjectNative)

src/coreclr/vm/eeconfig.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ HRESULT EEConfig::Init()
170170
#ifdef FEATURE_COMINTEROP
171171
bLogCCWRefCountChange = false;
172172
pszLogCCWRefCountChange = NULL;
173+
m_fBuiltInCOMInteropSupported = true;
173174
#endif // FEATURE_COMINTEROP
174175

175176
#ifdef _DEBUG
@@ -682,6 +683,7 @@ HRESULT EEConfig::sync()
682683
bLogCCWRefCountChange = true;
683684

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

687689
#ifdef _DEBUG

0 commit comments

Comments
 (0)