From 0881055dbc26c6a882ab5780c01cad270d3d2a60 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Thu, 29 Sep 2022 18:43:42 -0700 Subject: [PATCH 1/3] Remove IDispatchImplAttribute API This type has never been supported on .NET Core. Removing all supporting code paths. --- src/coreclr/vm/comcallablewrapper.cpp | 76 ----------- src/coreclr/vm/comcallablewrapper.h | 8 +- src/coreclr/vm/stdinterfaces.cpp | 119 ------------------ src/coreclr/vm/stdinterfaces_internal.h | 28 ----- src/coreclr/vm/wellknownattributes.h | 3 - .../src/MatchingRefApiCompatBaseline.txt | 2 - .../src/System.Runtime.InteropServices.csproj | 2 - .../InteropServices/IDispatchImplAttribute.cs | 18 --- .../InteropServices/IDispatchImplType.cs | 13 -- 9 files changed, 1 insertion(+), 268 deletions(-) delete mode 100644 src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplAttribute.cs delete mode 100644 src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplType.cs diff --git a/src/coreclr/vm/comcallablewrapper.cpp b/src/coreclr/vm/comcallablewrapper.cpp index e0c5c063ac26cb..0064fb391a55b3 100644 --- a/src/coreclr/vm/comcallablewrapper.cpp +++ b/src/coreclr/vm/comcallablewrapper.cpp @@ -43,14 +43,6 @@ #include "appdomain.inl" #include "typestring.h" -// The enum that describes the value of the IDispatchImplAttribute custom attribute. -enum IDispatchImplType -{ - SystemDefinedImpl = 0, - InternalImpl = 1, - CompatibleImpl = 2 -}; - // The enum that describe the value of System.Runtime.InteropServices.CustomQueryInterfaceResult // It is the return value of the method System.Runtime.InteropServices.ICustomQueryInterface.GetInterface enum CustomQueryInterfaceResult @@ -318,68 +310,6 @@ ComCallMethodDesc* ComMethodTable::ComCallMethodDescFromSlot(unsigned i) RETURN pCMD; } -//-------------------------------------------------------------------------- -// Determines if the Compatible IDispatch implementation is required for -// the specified class. -//-------------------------------------------------------------------------- -bool IsOleAutDispImplRequiredForClass(MethodTable *pClass) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(CheckPointer(pClass)); - } - CONTRACTL_END; - - HRESULT hr; - const BYTE * pVal; - ULONG cbVal; - Assembly * pAssembly = pClass->GetAssembly(); - IDispatchImplType DispImplType = SystemDefinedImpl; - - // First check for the IDispatchImplType custom attribute first. - hr = pClass->GetCustomAttribute(WellKnownAttribute::IDispatchImpl, (const void**)&pVal, &cbVal); - if (hr == S_OK) - { - CustomAttributeParser cap(pVal, cbVal); - IfFailThrow(cap.SkipProlog()); - UINT8 u1; - IfFailThrow(cap.GetU1(&u1)); - - DispImplType = (IDispatchImplType)u1; - if ((DispImplType > 2) || (DispImplType < 0)) - DispImplType = SystemDefinedImpl; - } - - // If the custom attribute was set to something other than system defined then we will use that. - if (DispImplType != SystemDefinedImpl) - return (bool) (DispImplType == CompatibleImpl); - - // Check to see if the assembly has the IDispatchImplType attribute set. - hr = pAssembly->GetCustomAttribute(pAssembly->GetManifestToken(), WellKnownAttribute::IDispatchImpl, (const void**)&pVal, &cbVal); - if (hr == S_OK) - { - CustomAttributeParser cap(pVal, cbVal); - IfFailThrow(cap.SkipProlog()); - UINT8 u1; - IfFailThrow(cap.GetU1(&u1)); - - DispImplType = (IDispatchImplType)u1; - if ((DispImplType > 2) || (DispImplType < 0)) - DispImplType = SystemDefinedImpl; - } - - // If the custom attribute was set to something other than system defined then we will use that. - if (DispImplType != SystemDefinedImpl) - return (bool) (DispImplType == CompatibleImpl); - - // Removed registry key check per reg cleanup bug 45978 - // Effect: Will return false so code cleanup - return false; -} - //-------------------------------------------------------------------------- // This routine is called anytime a com method is invoked for the first time. // It is responsible for generating the real stub. @@ -4733,12 +4663,6 @@ ComCallWrapperTemplate* ComCallWrapperTemplate::CreateTemplate(TypeHandle thClas pTemplate->m_flags |= enum_SupportsIClassX; } - if (IsOleAutDispImplRequiredForClass(pMT)) - { - // Determine what IDispatch implementation this class should use - pTemplate->m_flags |= enum_UseOleAutDispatchImpl; - } - // Eagerly create the interface CMTs. // when iterate the interfaces implemented by the methodtable, we can check whether // the interface supports ICustomQueryInterface. diff --git a/src/coreclr/vm/comcallablewrapper.h b/src/coreclr/vm/comcallablewrapper.h index d4b0ebfb277b8a..71b79ca0029934 100644 --- a/src/coreclr/vm/comcallablewrapper.h +++ b/src/coreclr/vm/comcallablewrapper.h @@ -255,12 +255,6 @@ class ComCallWrapperTemplate return (m_flags & enum_RepresentsVariantInterface); } - BOOL IsUseOleAutDispatchImpl() - { - LIMITED_METHOD_CONTRACT; - return (m_flags & enum_UseOleAutDispatchImpl); - } - BOOL ImplementsIMarshal() { LIMITED_METHOD_CONTRACT; @@ -327,7 +321,7 @@ class ComCallWrapperTemplate enum_RepresentsVariantInterface = 0x400, // this is a template for an interface with variance - enum_UseOleAutDispatchImpl = 0x800, // the class is decorated with IDispatchImplAttribute(CompatibleImpl) + // enum_Unused = 0x800, enum_ImplementsIMarshal = 0x1000, // the class implements a managed interface with Guid == IID_IMarshal diff --git a/src/coreclr/vm/stdinterfaces.cpp b/src/coreclr/vm/stdinterfaces.cpp index 44022ca573bbe2..3308a42366d08d 100644 --- a/src/coreclr/vm/stdinterfaces.cpp +++ b/src/coreclr/vm/stdinterfaces.cpp @@ -1173,11 +1173,6 @@ Dispatch_GetIDsOfNames(IDispatch* pDisp, REFIID riid, _In_reads_(cNames) OLECHAR return E_NOTIMPL; ComCallWrapperTemplate *pTemplate = MapIUnknownToWrapper(pDisp)->GetComCallWrapperTemplate(); - if (pTemplate->IsUseOleAutDispatchImpl()) - { - return OleAutDispatchImpl_GetIDsOfNames(pDisp, riid, rgszNames, cNames, lcid, rgdispid); - } - return InternalDispatchImpl_GetIDsOfNames(pDisp, riid, rgszNames, cNames, lcid, rgdispid); } @@ -1213,123 +1208,9 @@ Dispatch_Invoke return E_NOTIMPL; ComCallWrapperTemplate *pTemplate = MapIUnknownToWrapper(pDisp)->GetComCallWrapperTemplate(); - if (pTemplate->IsUseOleAutDispatchImpl()) - { - return OleAutDispatchImpl_Invoke(pDisp, dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); - } - return InternalDispatchImpl_Invoke(pDisp, dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); } - -//------------------------------------------------------------------------------------------ -// IDispatch methods for COM+ objects implemented internally using reflection. - - -HRESULT __stdcall -OleAutDispatchImpl_GetIDsOfNames -( - IDispatch* pDisp, - REFIID riid, - _In_reads_(cNames) OLECHAR **rgszNames, - unsigned int cNames, - LCID lcid, - DISPID *rgdispid -) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - INJECT_FAULT(return E_OUTOFMEMORY); - PRECONDITION(CheckPointer(pDisp)); - PRECONDITION(IsInProcCCWTearOff(pDisp)); - PRECONDITION(CheckPointer(rgszNames)); - } - CONTRACTL_END; - - // Make sure that riid is IID_NULL. - if (riid != IID_NULL) - return DISP_E_UNKNOWNINTERFACE; - - // Retrieve the COM method table from the IP. - ComMethodTable *pCMT = ComMethodTable::ComMethodTableFromIP(pDisp); - if (pCMT->IsIClassXOrBasicItf() && pCMT->GetClassInterfaceType() != clsIfNone) - if (pCMT->HasInvisibleParent()) - return E_NOTIMPL; - - ITypeInfo *pTI; - HRESULT hr = GetITypeInfoForMT(pCMT, &pTI); - if (FAILED(hr)) - return (hr); - - hr = pTI->GetIDsOfNames(rgszNames, cNames, rgdispid); - return hr; -} - -HRESULT __stdcall -OleAutDispatchImpl_Invoke - ( - IDispatch* pDisp, - DISPID dispidMember, - REFIID riid, - LCID lcid, - unsigned short wFlags, - DISPPARAMS *pdispparams, - VARIANT *pvarResult, - EXCEPINFO *pexcepinfo, - unsigned int *puArgErr - ) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - PRECONDITION(CheckPointer(pDisp)); - PRECONDITION(IsInProcCCWTearOff(pDisp)); - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - // Make sure that riid is IID_NULL. - if (riid != IID_NULL) - return DISP_E_UNKNOWNINTERFACE; - - // Retrieve the COM method table from the IP. - ComMethodTable *pCMT = ComMethodTable::ComMethodTableFromIP(pDisp); - if (pCMT->IsIClassXOrBasicItf() && pCMT->GetClassInterfaceType() != clsIfNone) - if (pCMT->HasInvisibleParent()) - return E_NOTIMPL; - - ITypeInfo *pTI; - hr = GetITypeInfoForMT(pCMT, &pTI); - if (FAILED(hr)) - return hr; - - EX_TRY - { - // If we have a basic or IClassX interface then we're going to invoke through - // the class interface. - if (pCMT->IsIClassXOrBasicItf()) - { - CCWHolder pCCW = ComCallWrapper::GetWrapperFromIP(pDisp); - pDisp = (IDispatch*)pCCW->GetIClassXIP(); - } - - hr = pTI->Invoke(pDisp, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - return hr; -} - HRESULT __stdcall InternalDispatchImpl_GetIDsOfNames ( IDispatch* pDisp, diff --git a/src/coreclr/vm/stdinterfaces_internal.h b/src/coreclr/vm/stdinterfaces_internal.h index bd1b7b336a2a0b..a268f566cdade9 100644 --- a/src/coreclr/vm/stdinterfaces_internal.h +++ b/src/coreclr/vm/stdinterfaces_internal.h @@ -93,34 +93,6 @@ HRESULT __stdcall Dispatch_Invoke ( EXCEPINFO *pexcepinfo, unsigned int *puArgErr); - -//------------------------------------------------------------------------------------------ -// IDispatch methods for COM+ objects that use our OleAut's implementation. - - -// IDispatch::GetIDsofNames -HRESULT __stdcall OleAutDispatchImpl_GetIDsOfNames ( - IDispatch* pDisp, - REFIID riid, - _In_reads_(cNames) OLECHAR **rgszNames, - unsigned int cNames, - LCID lcid, - DISPID *rgdispid); - -// IDispatch::Invoke -HRESULT __stdcall OleAutDispatchImpl_Invoke ( - IDispatch* pDisp, - DISPID dispidMember, - REFIID riid, - LCID lcid, - unsigned short wFlags, - DISPPARAMS *pdispparams, - VARIANT *pvarResult, - EXCEPINFO *pexcepinfo, - unsigned int *puArgErr); - - - //------------------------------------------------------------------------------------------ // IDispatch methods for COM+ objects that use our internal implementation. diff --git a/src/coreclr/vm/wellknownattributes.h b/src/coreclr/vm/wellknownattributes.h index b247d62e052d15..f1ac8a69767505 100644 --- a/src/coreclr/vm/wellknownattributes.h +++ b/src/coreclr/vm/wellknownattributes.h @@ -22,7 +22,6 @@ enum class WellKnownAttribute : DWORD DefaultDllImportSearchPaths, Guid, LCIDConversion, - IDispatchImpl, ImportedFromTypeLib, Intrinsic, IsByRefLike, @@ -77,8 +76,6 @@ inline const char *GetWellKnownAttributeName(WellKnownAttribute attribute) return "System.Runtime.InteropServices.GuidAttribute"; case WellKnownAttribute::LCIDConversion: return "System.Runtime.InteropServices.LCIDConversionAttribute"; - case WellKnownAttribute::IDispatchImpl: - return "System.Runtime.InteropServices.IDispatchImplAttribute"; case WellKnownAttribute::ImportedFromTypeLib: return "System.Runtime.InteropServices.ImportedFromTypeLibAttribute"; case WellKnownAttribute::Intrinsic: diff --git a/src/libraries/System.Runtime.InteropServices/src/MatchingRefApiCompatBaseline.txt b/src/libraries/System.Runtime.InteropServices/src/MatchingRefApiCompatBaseline.txt index dd2e06b69c3c29..adf9d5b07e0ed5 100644 --- a/src/libraries/System.Runtime.InteropServices/src/MatchingRefApiCompatBaseline.txt +++ b/src/libraries/System.Runtime.InteropServices/src/MatchingRefApiCompatBaseline.txt @@ -2,8 +2,6 @@ Compat issues with assembly System.Runtime.InteropServices: TypesMustExist : Type 'System.Runtime.InteropServices.AssemblyRegistrationFlags' does not exist in the reference but it does exist in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Runtime.InteropServices.ComWrappers' changed from '[UnsupportedOSPlatformAttribute("android")]' in the implementation to '[UnsupportedOSPlatformAttribute("android")]' in the reference. TypesMustExist : Type 'System.Runtime.InteropServices.ExporterEventKind' does not exist in the reference but it does exist in the implementation. -TypesMustExist : Type 'System.Runtime.InteropServices.IDispatchImplAttribute' does not exist in the reference but it does exist in the implementation. -TypesMustExist : Type 'System.Runtime.InteropServices.IDispatchImplType' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'System.Runtime.InteropServices.RegistrationClassContext' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'System.Runtime.InteropServices.RegistrationConnectionType' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'System.Runtime.InteropServices.SetWin32ContextInIDispatchAttribute' does not exist in the reference but it does exist in the implementation. diff --git a/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj b/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj index fc2048c219ac98..99e288f8de5019 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj +++ b/src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj @@ -29,8 +29,6 @@ - - diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplAttribute.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplAttribute.cs deleted file mode 100644 index dfe2ad08ddb266..00000000000000 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplAttribute.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.InteropServices -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)] - [Obsolete("IDispatchImplAttribute has been deprecated and is not supported.")] - public sealed class IDispatchImplAttribute : Attribute - { - public IDispatchImplAttribute(short implType) : this((IDispatchImplType)implType) - { - } - - public IDispatchImplAttribute(IDispatchImplType implType) => Value = implType; - - public IDispatchImplType Value { get; } - } -} diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplType.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplType.cs deleted file mode 100644 index fe674c3954cbda..00000000000000 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/IDispatchImplType.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.InteropServices -{ - [Obsolete("IDispatchImplAttribute and IDispatchImplType have been deprecated and are not supported.")] - public enum IDispatchImplType - { - CompatibleImpl = 2, - InternalImpl = 1, - SystemDefinedImpl = 0, - } -} From 463e51247248f0471c03682acb4ec5982c1e81ee Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Thu, 29 Sep 2022 22:02:54 -0700 Subject: [PATCH 2/3] Remove unit testing --- .../tests/Resources/Interop/Interop.Mock01.cs | 1 - ...ystem.Runtime.InteropServices.Tests.csproj | 1 - .../IDispatchImplAttributeTests.cs | 27 ------------------- 3 files changed, 29 deletions(-) delete mode 100644 src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/IDispatchImplAttributeTests.cs diff --git a/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs b/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs index 0ad8ac99a04ec4..ef6ab5b7f20f79 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs @@ -17,7 +17,6 @@ [assembly: ComVisible(true)] // not embed [assembly: TypeLibVersion(1, 0)] // not embed // [assembly: SetWin32ContextInIDispatch()] -// [assembly: IDispatchImpl(IDispatchImplType.CompatibleImpl)] // not embed namespace MockInterop01 { diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj index 34964fb33f2ab7..867c373eea2a9e 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj @@ -44,7 +44,6 @@ - diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/IDispatchImplAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/IDispatchImplAttributeTests.cs deleted file mode 100644 index ac192126f64891..00000000000000 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/IDispatchImplAttributeTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; -using Xunit; - -namespace System.Runtime.InteropServices.Tests -{ - public class IDispatchImplAttributeTests - { - [Theory] - [InlineData(-1)] - [InlineData(0)] - [InlineData(2)] - public void Ctor_ImplTypeShort(short implType) - { - Type type = Type.GetType("System.Runtime.InteropServices.IDispatchImplAttribute, System.Runtime.InteropServices"); - PropertyInfo valueProperty = type.GetProperty("Value"); - Assert.NotNull(type); - Assert.NotNull(valueProperty); - - ConstructorInfo shortConstructor = type.GetConstructor(new Type[] { typeof(short) }); - object attribute = shortConstructor.Invoke(new object[] { implType }); - Assert.Equal(implType, (int)valueProperty.GetValue(attribute)); - } - } -} From 4cbb24f5e0b91b95c73a80e584751c646b7ce08c Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Fri, 30 Sep 2022 13:03:54 -0700 Subject: [PATCH 3/3] Apply suggestions from code review --- src/coreclr/vm/stdinterfaces.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/vm/stdinterfaces.cpp b/src/coreclr/vm/stdinterfaces.cpp index 3308a42366d08d..cffce984a04a3c 100644 --- a/src/coreclr/vm/stdinterfaces.cpp +++ b/src/coreclr/vm/stdinterfaces.cpp @@ -1172,7 +1172,6 @@ Dispatch_GetIDsOfNames(IDispatch* pDisp, REFIID riid, _In_reads_(cNames) OLECHAR if (pCMT->HasInvisibleParent()) return E_NOTIMPL; - ComCallWrapperTemplate *pTemplate = MapIUnknownToWrapper(pDisp)->GetComCallWrapperTemplate(); return InternalDispatchImpl_GetIDsOfNames(pDisp, riid, rgszNames, cNames, lcid, rgdispid); } @@ -1207,7 +1206,6 @@ Dispatch_Invoke if (pCMT->HasInvisibleParent()) return E_NOTIMPL; - ComCallWrapperTemplate *pTemplate = MapIUnknownToWrapper(pDisp)->GetComCallWrapperTemplate(); return InternalDispatchImpl_Invoke(pDisp, dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); }