From 431901a5c292b244874901ab1d8df06884c39d6a Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Sat, 26 Jan 2019 03:32:24 +0100 Subject: [PATCH] Move more Marshal methods to shared partition (dotnet/coreclr#22205) * Move more Marshal methods to shared partition * Implement ThrowExceptionForHR in managed Commit migrated from https://github.com/dotnet/coreclr/commit/bb734dc0df68229e37d11dbdb8aee70e6aff73e4 --- .../Runtime/InteropServices/Marshal.CoreCLR.cs | 86 ---------------------- src/coreclr/src/vm/ecalllist.h | 1 - src/coreclr/src/vm/marshalnative.cpp | 33 --------- src/coreclr/src/vm/marshalnative.h | 1 - .../src/System/Runtime/InteropServices/Marshal.cs | 79 +++++++++++++++++++- 5 files changed, 78 insertions(+), 122 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 4881b27..0dcda59 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -212,17 +212,6 @@ namespace System.Runtime.InteropServices [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void SetLastWin32Error(int error); - public static int GetHRForLastWin32Error() - { - int dwLastError = GetLastWin32Error(); - if ((dwLastError & 0x80000000) == 0x80000000) - { - return dwLastError; - } - - return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000); - } - private static void PrelinkCore(MethodInfo m) { if (!(m is RuntimeMethodInfo rmi)) @@ -299,28 +288,6 @@ namespace System.Runtime.InteropServices #endif // FEATURE_COMINTEROP - /// - /// Throws a CLR exception based on the HRESULT. - /// - public static void ThrowExceptionForHR(int errorCode) - { - if (errorCode < 0) - { - ThrowExceptionForHRInternal(errorCode, IntPtr.Zero); - } - } - - public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo) - { - if (errorCode < 0) - { - ThrowExceptionForHRInternal(errorCode, errorInfo); - } - } - - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ThrowExceptionForHRInternal(int errorCode, IntPtr errorInfo); - [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Exception GetExceptionForHRInternal(int errorCode, IntPtr errorInfo); @@ -349,8 +316,6 @@ namespace System.Runtime.InteropServices return pNewMem; } - public static IntPtr AllocHGlobal(int cb) => AllocHGlobal((IntPtr)cb); - public static void FreeHGlobal(IntPtr hglobal) { if (!IsWin32Atom(hglobal)) @@ -488,11 +453,7 @@ namespace System.Runtime.InteropServices /// [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IntPtr /* IUnknown* */ GetRawIUnknownForComObjectNoAddRef(object o); -#endif // FEATURE_COMINTEROP - public static IntPtr /* IDispatch */ GetIDispatchForObject(object o) => throw new PlatformNotSupportedException(); - -#if FEATURE_COMINTEROP /// /// Return the IUnknown* representing the interface for the Object. /// Object o should support Type T @@ -943,54 +904,7 @@ namespace System.Runtime.InteropServices /// [MethodImpl(MethodImplOptions.InternalCall)] public static extern int GetEndComSlot(Type t); -#endif // FEATURE_COMINTEROP - - /// - /// This method generates a PROGID for the specified type. If the type has - /// a PROGID in the metadata then it is returned otherwise a stable PROGID - /// is generated based on the fully qualified name of the type. - /// - public static string GenerateProgIdForType(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - if (type.IsImport) - { - throw new ArgumentException(SR.Argument_TypeMustNotBeComImport, nameof(type)); - } - if (type.IsGenericType) - { - throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); - } - IList cas = CustomAttributeData.GetCustomAttributes(type); - for (int i = 0; i < cas.Count; i++) - { - if (cas[i].Constructor.DeclaringType == typeof(ProgIdAttribute)) - { - // Retrieve the PROGID string from the ProgIdAttribute. - IList caConstructorArgs = cas[i].ConstructorArguments; - Debug.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1"); - - CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0]; - Debug.Assert(progIdConstructorArg.ArgumentType == typeof(string), "progIdConstructorArg.ArgumentType == typeof(String)"); - - string strProgId = (string)progIdConstructorArg.Value; - - if (strProgId == null) - strProgId = string.Empty; - - return strProgId; - } - } - - // If there is no prog ID attribute then use the full name of the type as the prog id. - return type.FullName; - } - -#if FEATURE_COMINTEROP public static object BindToMoniker(string monikerName) { CreateBindCtx(0, out IBindCtx bindctx); diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 83dadce..fb182e3 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -817,7 +817,6 @@ FCFuncStart(gInteropMarshalFuncs) FCFuncElement("OffsetOfHelper", MarshalNative::OffsetOfHelper) QCFuncElement("InternalPrelink", MarshalNative::Prelink) - FCFuncElement("ThrowExceptionForHRInternal", MarshalNative::ThrowExceptionForHR) FCFuncElement("GetExceptionForHRInternal", MarshalNative::GetExceptionForHR) FCFuncElement("GetDelegateForFunctionPointerInternal", MarshalNative::GetDelegateForFunctionPointerInternal) FCFuncElement("GetFunctionPointerForDelegateInternal", MarshalNative::GetFunctionPointerForDelegateInternal) diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp index 6e71c08..908a7b3 100644 --- a/src/coreclr/src/vm/marshalnative.cpp +++ b/src/coreclr/src/vm/marshalnative.cpp @@ -731,39 +731,6 @@ FCIMPL2(Object *, MarshalNative::GetExceptionForHR, INT32 errorCode, LPVOID erro return OBJECTREFToObject(RetExceptionObj); } FCIMPLEND - -FCIMPL2(void, MarshalNative::ThrowExceptionForHR, INT32 errorCode, LPVOID errorInfo) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(FAILED(errorCode)); - PRECONDITION(CheckPointer(errorInfo, NULL_OK)); - } - CONTRACTL_END; - - - HELPER_METHOD_FRAME_BEGIN_0(); - - // Retrieve the IErrorInfo to use. - IErrorInfo *pErrorInfo = (IErrorInfo*)errorInfo; - if (pErrorInfo == (IErrorInfo*)(-1)) - { - pErrorInfo = NULL; - } - else if (!pErrorInfo) - { - if (SafeGetErrorInfo(&pErrorInfo) != S_OK) - pErrorInfo = NULL; - } - - // Throw the exception based on the HR and the IErrorInfo. - COMPlusThrowHR(errorCode, pErrorInfo); - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - FCIMPL1(int, MarshalNative::GetHRForException, Object* eUNSAFE) { diff --git a/src/coreclr/src/vm/marshalnative.h b/src/coreclr/src/vm/marshalnative.h index 53a9966..8f31688 100644 --- a/src/coreclr/src/vm/marshalnative.h +++ b/src/coreclr/src/vm/marshalnative.h @@ -44,7 +44,6 @@ public: //==================================================================== // These methods convert between an HR and and a managed exception. //==================================================================== - static FCDECL2(void, ThrowExceptionForHR, INT32 errorCode, LPVOID errorInfo); static FCDECL2(Object *, GetExceptionForHR, INT32 errorCode, LPVOID errorInfo); static FCDECL1(int, GetHRForException, Object* eUNSAFE); static FCDECL1(int, GetHRForException_WinRT, Object* eUNSAFE); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs index dd59b03..3929523 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Diagnostics; using System.Security; using System.Reflection; using System.Runtime.CompilerServices; @@ -29,6 +31,8 @@ namespace System.Runtime.InteropServices /// public static readonly int SystemMaxDBCSCharSize = GetSystemMaxDBCSCharSize(); + public static IntPtr AllocHGlobal(int cb) => AllocHGlobal((IntPtr)cb); + public static unsafe string PtrToStringAnsi(IntPtr ptr) { if (ptr == IntPtr.Zero || IsWin32Atom(ptr)) @@ -578,6 +582,25 @@ namespace System.Runtime.InteropServices return GetExceptionForHRInternal(errorCode, errorInfo); } + /// + /// Throws a CLR exception based on the HRESULT. + /// + public static void ThrowExceptionForHR(int errorCode) + { + if (errorCode < 0) + { + throw GetExceptionForHR(errorCode, IntPtr.Zero); + } + } + + public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo) + { + if (errorCode < 0) + { + throw GetExceptionForHR(errorCode, errorInfo); + } + } + public static IntPtr SecureStringToBSTR(SecureString s) { if (s == null) @@ -647,6 +670,47 @@ namespace System.Runtime.InteropServices return type.GUID; } + /// + /// This method generates a PROGID for the specified type. If the type has + /// a PROGID in the metadata then it is returned otherwise a stable PROGID + /// is generated based on the fully qualified name of the type. + /// + public static string GenerateProgIdForType(Type type) + { + if (type == null) + { + throw new ArgumentNullException(nameof(type)); + } + if (type.IsImport) + { + throw new ArgumentException(SR.Argument_TypeMustNotBeComImport, nameof(type)); + } + if (type.IsGenericType) + { + throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); + } + + foreach (CustomAttributeData cad in type.GetCustomAttributesData()) + { + if (cad.Constructor.DeclaringType == typeof(ProgIdAttribute)) + { + // Retrieve the PROGID string from the ProgIdAttribute. + IList caConstructorArgs = cad.ConstructorArguments; + Debug.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1"); + + CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0]; + Debug.Assert(progIdConstructorArg.ArgumentType == typeof(string), "progIdConstructorArg.ArgumentType == typeof(string)"); + + string strProgId = (string)progIdConstructorArg.Value; + + return strProgId ?? string.Empty; + } + } + + // If there is no prog ID attribute then use the full name of the type as the prog id. + return type.FullName; + } + public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t) { if (ptr == IntPtr.Zero) @@ -694,5 +758,18 @@ namespace System.Runtime.InteropServices { return GetFunctionPointerForDelegate((Delegate)(object)d); } + + public static int GetHRForLastWin32Error() + { + int dwLastError = GetLastWin32Error(); + if ((dwLastError & 0x80000000) == 0x80000000) + { + return dwLastError; + } + + return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000); + } + + public static IntPtr /* IDispatch */ GetIDispatchForObject(object o) => throw new PlatformNotSupportedException(); } -} \ No newline at end of file +} -- 2.7.4