diff options
author | Jeremy Koritzinsky <jkoritzinsky@gmail.com> | 2019-03-22 17:09:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-22 17:09:21 -0700 |
commit | acd1164c8c89582f13163e309a0183c72bc13924 (patch) | |
tree | 831ab704ef87ed1a5b9e1a32be0c4df24b7af736 | |
parent | 017ded3c6acd653b875f4ef12c232617855dea09 (diff) | |
download | coreclr-acd1164c8c89582f13163e309a0183c72bc13924.tar.gz coreclr-acd1164c8c89582f13163e309a0183c72bc13924.tar.bz2 coreclr-acd1164c8c89582f13163e309a0183c72bc13924.zip |
Fix WinRT marshalling for NotifyPropertyChangedEventArgs and NotifyCollectionChangedEventArgs (CoreCLR side) (#23401)
* Enable marshalling IntPtr and UIntPtr in WinRT scenarios to support our marshalling infrastructure.
* Enable getting an RCW for a native COM object while ignoring WinRT projections.
* Rename to Marshal.GetUniqueObjectForIUnknownWithoutUnboxing
* Clean up contract.
* Move GetUniqueObjectForIUnknownWithoutUnboxing to WindowsRuntimeMarshal.
* Move WinRT-specific FCalls to WindowsRuntimeMarshal.
-rw-r--r-- | src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs | 24 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs | 33 | ||||
-rw-r--r-- | src/vm/dllimport.cpp | 4 | ||||
-rw-r--r-- | src/vm/ecalllist.h | 17 | ||||
-rw-r--r-- | src/vm/marshalnative.cpp | 22 | ||||
-rw-r--r-- | src/vm/marshalnative.h | 5 | ||||
-rw-r--r-- | src/vm/mlinfo.cpp | 17 | ||||
-rw-r--r-- | src/vm/mscorlib.h | 4 |
8 files changed, 75 insertions, 51 deletions
diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 4cdf838fb1..e399ad6100 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -309,15 +309,6 @@ namespace System.Runtime.InteropServices public static extern int GetHRForException(Exception e); /// <summary> - /// Converts the CLR exception to an HRESULT. This function also sets - /// up an IErrorInfo for the exception. - /// This function is only used in WinRT and converts ObjectDisposedException - /// to RO_E_CLOSED - /// </summary> - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern int GetHRForException_WinRT(Exception e); - - /// <summary> /// Given a managed object that wraps an ITypeInfo, return its name. /// </summary> public static string GetTypeInfoName(ITypeInfo typeInfo) @@ -743,21 +734,6 @@ namespace System.Runtime.InteropServices [MethodImpl(MethodImplOptions.InternalCall)] public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak); - - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void InitializeWrapperForWinRT(object o, ref IntPtr pUnk); - -#if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void InitializeManagedWinRTFactoryObject(object o, RuntimeType runtimeClassType); -#endif - - /// <summary> - /// Create activation factory and wraps it with a unique RCW. - /// </summary> - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern object GetNativeActivationFactory(Type type); - #endif // FEATURE_COMINTEROP [MethodImpl(MethodImplOptions.InternalCall)] diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs index 3199d2e239..5a151e7de2 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs @@ -1155,7 +1155,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime Marshal.QueryInterface(exceptionIUnknown, ref s_iidIErrorInfo, out exceptionIErrorInfo); if (exceptionIErrorInfo != IntPtr.Zero) { - if (RoOriginateLanguageException(Marshal.GetHRForException_WinRT(e), e.Message, exceptionIErrorInfo)) + if (RoOriginateLanguageException(Marshal.GetHRForException(e), e.Message, exceptionIErrorInfo)) { IRestrictedErrorInfo restrictedError = UnsafeNativeMethods.GetRestrictedErrorInfo(); if (restrictedError != null) @@ -1199,7 +1199,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime // If the type has any associated factory interfaces (i.e. supports non-default activation // or has statics), the CCW for this instance of ManagedActivationFactory must support them. - Marshal.InitializeManagedWinRTFactoryObject(activationFactory, (RuntimeType)type); + InitializeManagedWinRTFactoryObject(activationFactory, (RuntimeType)type); return activationFactory; } @@ -1223,7 +1223,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime if (type.IsWindowsRuntimeObject && type.IsImport) { - return (IActivationFactory)Marshal.GetNativeActivationFactory(type); + return (IActivationFactory)GetNativeActivationFactory(type); } else { @@ -1276,6 +1276,33 @@ namespace System.Runtime.InteropServices.WindowsRuntime } } + [MethodImpl(MethodImplOptions.InternalCall)] + public static extern object GetUniqueObjectForIUnknownWithoutUnboxing(IntPtr unknown); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void InitializeWrapper(object o, ref IntPtr pUnk); + + /// <summary> + /// Converts the CLR exception to an HRESULT. This function also sets + /// up an IErrorInfo for the exception. + /// This function is only used in WinRT and converts ObjectDisposedException + /// to RO_E_CLOSED + /// </summary> + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern int GetHRForException(Exception e); + + +#if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void InitializeManagedWinRTFactoryObject(object o, RuntimeType runtimeClassType); +#endif + + /// <summary> + /// Create activation factory and wraps it with a unique RCW. + /// </summary> + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern object GetNativeActivationFactory(Type type); + [Conditional("_LOGGING")] private static void Log(string s) { diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp index f4c2838385..b200a1bccb 100644 --- a/src/vm/dllimport.cpp +++ b/src/vm/dllimport.cpp @@ -401,7 +401,7 @@ public: pcsUnmarshal->EmitLDLOCA(dwFactoryRetValLocalNum); } - pcsUnmarshal->EmitCALL(METHOD__MARSHAL__INITIALIZE_WRAPPER_FOR_WINRT, 2, 0); + pcsUnmarshal->EmitCALL(METHOD__WINDOWSRUNTIMEMARSHAL__INITIALIZE_WRAPPER, 2, 0); /* * CLEANUP @@ -650,7 +650,7 @@ public: BinderMethodID getHRForException; if (SF_IsWinRTStub(m_dwStubFlags)) { - getHRForException = METHOD__MARSHAL__GET_HR_FOR_EXCEPTION_WINRT; + getHRForException = METHOD__WINDOWSRUNTIMEMARSHAL__GET_HR_FOR_EXCEPTION; } else { diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h index c184633221..ae98cff196 100644 --- a/src/vm/ecalllist.h +++ b/src/vm/ecalllist.h @@ -818,7 +818,6 @@ FCFuncStart(gInteropMarshalFuncs) #ifdef FEATURE_COMINTEROP FCFuncElement("GetHRForException", MarshalNative::GetHRForException) - FCFuncElement("GetHRForException_WinRT", MarshalNative::GetHRForException_WinRT) FCFuncElement("GetRawIUnknownForComObjectNoAddRef", MarshalNative::GetRawIUnknownForComObjectNoAddRef) FCFuncElement("IsComObject", MarshalNative::IsComObject) FCFuncElement("GetObjectForIUnknown", MarshalNative::GetObjectForIUnknown) @@ -835,21 +834,26 @@ FCFuncStart(gInteropMarshalFuncs) FCFuncElement("GetObjectsForNativeVariants", MarshalNative::GetObjectsForNativeVariants) FCFuncElement("GetStartComSlot", MarshalNative::GetStartComSlot) FCFuncElement("GetEndComSlot", MarshalNative::GetEndComSlot) - - FCFuncElement("InitializeManagedWinRTFactoryObject", MarshalNative::InitializeManagedWinRTFactoryObject) - - FCFuncElement("GetNativeActivationFactory", MarshalNative::GetNativeActivationFactory) FCFuncElement("GetIUnknownForObjectNative", MarshalNative::GetIUnknownForObjectNative) FCFuncElement("GetComInterfaceForObjectNative", MarshalNative::GetComInterfaceForObjectNative) FCFuncElement("InternalReleaseComObject", MarshalNative::ReleaseComObject) FCFuncElement("Release", MarshalNative::Release) - FCFuncElement("InitializeWrapperForWinRT", MarshalNative::InitializeWrapperForWinRT) FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown) FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength) FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext) #endif // FEATURE_COMINTEROP FCFuncEnd() +#ifdef FEATURE_COMINTEROP +FCFuncStart(gWindowsRuntimeMarshalFuncs) + FCFuncElement("GetNativeActivationFactory", MarshalNative::GetNativeActivationFactory) + FCFuncElement("GetHRForException", MarshalNative::GetHRForException_WinRT) + FCFuncElement("GetUniqueObjectForIUnknownWithoutUnboxing", MarshalNative::GetUniqueObjectForIUnknownWithoutUnboxing) + FCFuncElement("InitializeManagedWinRTFactoryObject", MarshalNative::InitializeManagedWinRTFactoryObject) + FCFuncElement("InitializeWrapper", MarshalNative::InitializeWrapperForWinRT) +FCFuncEnd() +#endif + FCFuncStart(gInteropNativeLibraryFuncs) QCFuncElement("LoadFromPath", NativeLibraryNative::LoadFromPath) QCFuncElement("LoadByName", NativeLibraryNative::LoadByName) @@ -1300,6 +1304,7 @@ FCClassElement("WeakReference`1", "System", gWeakReferenceOfTFuncs) #ifdef FEATURE_COMINTEROP FCClassElement("WinRTTypeNameConverter", "System.StubHelpers", gWinRTTypeNameConverterFuncs) +FCClassElement("WindowsRuntimeMarshal", "System.Runtime.InteropServices.WindowsRuntime", gWindowsRuntimeMarshalFuncs) #endif // FEATURE_COMINTEROP diff --git a/src/vm/marshalnative.cpp b/src/vm/marshalnative.cpp index 23df97dcb7..bd4ad09731 100644 --- a/src/vm/marshalnative.cpp +++ b/src/vm/marshalnative.cpp @@ -1024,6 +1024,28 @@ FCIMPL1(Object*, MarshalNative::GetUniqueObjectForIUnknown, IUnknown* pUnk) } FCIMPLEND +FCIMPL1(Object*, MarshalNative::GetUniqueObjectForIUnknownWithoutUnboxing, IUnknown* pUnk) +{ + FCALL_CONTRACT; + + OBJECTREF oref = NULL; + HELPER_METHOD_FRAME_BEGIN_RET_1(oref); + + HRESULT hr = S_OK; + + if(!pUnk) + COMPlusThrowArgumentNull(W("pUnk")); + + // Ensure COM is started up. + EnsureComStarted(); + + GetObjectRefFromComIP(&oref, pUnk, NULL, NULL, ObjFromComIP::UNIQUE_OBJECT | ObjFromComIP::IGNORE_WINRT_AND_SKIP_UNBOXING); + + HELPER_METHOD_FRAME_END(); + return OBJECTREFToObject(oref); +} +FCIMPLEND + //==================================================================== // return an Object for IUnknown, using the Type T, // NOTE: diff --git a/src/vm/marshalnative.h b/src/vm/marshalnative.h index eaadfacde0..bac0c2475d 100644 --- a/src/vm/marshalnative.h +++ b/src/vm/marshalnative.h @@ -122,6 +122,11 @@ public: static FCDECL1(Object*, GetUniqueObjectForIUnknown, IUnknown* pUnk); //==================================================================== + // return a unique cacheless Object for IUnknown + //==================================================================== + static FCDECL1(Object*, GetUniqueObjectForIUnknownWithoutUnboxing, IUnknown* pUnk); + + //==================================================================== // return an Object for IUnknown, using the Type T, // NOTE: // Type T should be either a COM imported Type or a sub-type of COM imported Type diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp index edbf759322..f861c43cf8 100644 --- a/src/vm/mlinfo.cpp +++ b/src/vm/mlinfo.cpp @@ -1875,13 +1875,9 @@ MarshalInfo::MarshalInfo(Module* pModule, break; case ELEMENT_TYPE_I: -#ifdef FEATURE_COMINTEROP - if (IsWinRTScenario()) - { - m_resID = IDS_EE_BADMARSHAL_WINRT_ILLEGAL_TYPE; - IfFailGoto(E_FAIL, lFail); - } -#endif // FEATURE_COMINTEROP + // Technically the "native int" and "native uint" types aren't supported in the WinRT scenario, + // but we need to not block ourselves from using them to enable accurate managed->native marshalling of + // projected types such as NotifyCollectionChangedEventArgs and NotifyPropertyChangedEventArgs. if (!(nativeType == NATIVE_TYPE_INT || nativeType == NATIVE_TYPE_UINT || nativeType == NATIVE_TYPE_DEFAULT)) { @@ -1892,13 +1888,6 @@ MarshalInfo::MarshalInfo(Module* pModule, break; case ELEMENT_TYPE_U: -#ifdef FEATURE_COMINTEROP - if (IsWinRTScenario()) - { - m_resID = IDS_EE_BADMARSHAL_WINRT_ILLEGAL_TYPE; - IfFailGoto(E_FAIL, lFail); - } -#endif // FEATURE_COMINTEROP if (!(nativeType == NATIVE_TYPE_UINT || nativeType == NATIVE_TYPE_INT || nativeType == NATIVE_TYPE_DEFAULT)) { diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h index 7cb76d3d9a..d2a0ad61fd 100644 --- a/src/vm/mscorlib.h +++ b/src/vm/mscorlib.h @@ -492,9 +492,7 @@ DEFINE_CLASS(LCID_CONVERSION_TYPE, Interop, LCIDConversionAttrib DEFINE_CLASS(MARSHAL, Interop, Marshal) #ifdef FEATURE_COMINTEROP -DEFINE_METHOD(MARSHAL, INITIALIZE_WRAPPER_FOR_WINRT, InitializeWrapperForWinRT, SM_Obj_RefIntPtr_RetVoid) DEFINE_METHOD(MARSHAL, GET_HR_FOR_EXCEPTION, GetHRForException, SM_Exception_RetInt) -DEFINE_METHOD(MARSHAL, GET_HR_FOR_EXCEPTION_WINRT, GetHRForException_WinRT, SM_Exception_RetInt) #endif // FEATURE_COMINTEROP DEFINE_METHOD(MARSHAL, GET_FUNCTION_POINTER_FOR_DELEGATE, GetFunctionPointerForDelegate, SM_Delegate_RetIntPtr) DEFINE_METHOD(MARSHAL, GET_DELEGATE_FOR_FUNCTION_POINTER, GetDelegateForFunctionPointer, SM_IntPtr_Type_RetDelegate) @@ -936,6 +934,8 @@ DEFINE_METHOD(BUFFER, MEMCPY, Memcpy, #ifdef FEATURE_COMINTEROP DEFINE_CLASS(WINDOWSRUNTIMEMARSHAL, WinRT, WindowsRuntimeMarshal) +DEFINE_METHOD(WINDOWSRUNTIMEMARSHAL, GET_HR_FOR_EXCEPTION, GetHRForException, SM_Exception_RetInt) +DEFINE_METHOD(WINDOWSRUNTIMEMARSHAL, INITIALIZE_WRAPPER, InitializeWrapper, SM_Obj_RefIntPtr_RetVoid) #ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION DEFINE_METHOD(WINDOWSRUNTIMEMARSHAL, GET_ACTIVATION_FACTORY_FOR_TYPE, GetActivationFactoryForType, SM_Type_RetIntPtr) #endif // FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION |