summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>2019-03-22 17:09:21 -0700
committerGitHub <noreply@github.com>2019-03-22 17:09:21 -0700
commitacd1164c8c89582f13163e309a0183c72bc13924 (patch)
tree831ab704ef87ed1a5b9e1a32be0c4df24b7af736
parent017ded3c6acd653b875f4ef12c232617855dea09 (diff)
downloadcoreclr-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.cs24
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs33
-rw-r--r--src/vm/dllimport.cpp4
-rw-r--r--src/vm/ecalllist.h17
-rw-r--r--src/vm/marshalnative.cpp22
-rw-r--r--src/vm/marshalnative.h5
-rw-r--r--src/vm/mlinfo.cpp17
-rw-r--r--src/vm/mscorlib.h4
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