From 0e9147967239e902eb7898fed2d4839fce2c7ec5 Mon Sep 17 00:00:00 2001 From: Manodasan Wignarajah Date: Thu, 8 Jun 2023 11:43:30 -0700 Subject: [PATCH] Minor improvements to error info (#1331) * Fix issue when lanaguage exception is proxied, error info is not set and minor improvements * Handle scenario where Net core fills in same fields as us. * Move to using static function for hashing --- src/WinRT.Runtime/ExceptionHelpers.cs | 31 ++++++++++--------- src/WinRT.Runtime/GuidGenerator.cs | 13 +++++--- .../Interop/ExceptionErrorInfo.cs | 3 -- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/WinRT.Runtime/ExceptionHelpers.cs b/src/WinRT.Runtime/ExceptionHelpers.cs index 6b9dee168..7d72697f2 100644 --- a/src/WinRT.Runtime/ExceptionHelpers.cs +++ b/src/WinRT.Runtime/ExceptionHelpers.cs @@ -34,7 +34,7 @@ static unsafe class ExceptionHelpers [DllImport("oleaut32.dll")] private static extern int SetErrorInfo(uint dwReserved, IntPtr perrinfo); - private static delegate* unmanaged[Stdcall] getRestrictedErrorInfo; + private static delegate* unmanaged[Stdcall] getRestrictedErrorInfo; private static delegate* unmanaged[Stdcall] setRestrictedErrorInfo; private static delegate* unmanaged[Stdcall] roOriginateLanguageException; private static delegate* unmanaged[Stdcall] roReportUnhandledError; @@ -56,7 +56,7 @@ private static bool Initialize() if (winRTErrorModule != IntPtr.Zero) { - getRestrictedErrorInfo = (delegate* unmanaged[Stdcall])Platform.GetProcAddress(winRTErrorModule, "GetRestrictedErrorInfo"); + getRestrictedErrorInfo = (delegate* unmanaged[Stdcall])Platform.GetProcAddress(winRTErrorModule, "GetRestrictedErrorInfo"); setRestrictedErrorInfo = (delegate* unmanaged[Stdcall])Platform.GetProcAddress(winRTErrorModule, "SetRestrictedErrorInfo"); } @@ -90,7 +90,8 @@ private static IObjectReference BorrowRestrictedErrorInfo() if (getRestrictedErrorInfo == null) return null; - Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(out IntPtr restrictedErrorInfoPtr)); + IntPtr restrictedErrorInfoPtr = IntPtr.Zero; + Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(&restrictedErrorInfoPtr)); if (restrictedErrorInfoPtr == IntPtr.Zero) return null; @@ -144,16 +145,15 @@ private static Exception GetExceptionForHR(int hr, bool useGlobalErrorState, out } else { + // This could also be a proxy to a managed exception. hasOtherLanguageException = true; } } } - else + + if (hr == hrLocal) { - if (hr == hrLocal) - { - restrictedErrorInfoRef.TryAs(out iErrorInfo); - } + restrictedErrorInfoRef.TryAs(out iErrorInfo); } } } @@ -309,15 +309,15 @@ internal static void AddExceptionDataForRestrictedErrorInfo( IDictionary dict = ex.Data; if (dict != null) { - dict.Add("Description", description); - dict.Add("RestrictedDescription", restrictedError); - dict.Add("RestrictedErrorReference", restrictedErrorReference); - dict.Add("RestrictedCapabilitySid", restrictedCapabilitySid); + dict["Description"] = description; + dict["RestrictedDescription"] = restrictedError; + dict["RestrictedErrorReference"] = restrictedErrorReference; + dict["RestrictedCapabilitySid"] = restrictedCapabilitySid; // Keep the error object alive so that user could retrieve error information // using Data["RestrictedErrorReference"] - dict.Add("__RestrictedErrorObjectReference", restrictedErrorObject == null ? null : new __RestrictedErrorObject(restrictedErrorObject)); - dict.Add("__HasRestrictedLanguageErrorObject", hasRestrictedLanguageErrorObject); + dict["__RestrictedErrorObjectReference"] = restrictedErrorObject == null ? null : new __RestrictedErrorObject(restrictedErrorObject); + dict["__HasRestrictedLanguageErrorObject"] = hasRestrictedLanguageErrorObject; } } @@ -353,7 +353,8 @@ public static Exception AttachRestrictedErrorInfo(Exception e) // HRESULT ABI return values. However, in many cases async APIs will set the thread's restricted // error info as a convention in order to provide extended debugging information for the ErrorCode // property. - Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(out IntPtr restrictedErrorInfoPtr)); + IntPtr restrictedErrorInfoPtr = IntPtr.Zero; + Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(&restrictedErrorInfoPtr)); if (restrictedErrorInfoPtr != IntPtr.Zero) { diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 5f7898ea7..21f8ccd80 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -160,6 +160,11 @@ public static Guid CreateIID(Type type) } #if !NET var data = wrt_pinterface_namespace.ToByteArray().Concat(UTF8Encoding.UTF8.GetBytes(sig)).ToArray(); + + using (SHA1 sha = new SHA1CryptoServiceProvider()) + { + return encode_guid(sha.ComputeHash(data)); + } #else var maxBytes = UTF8Encoding.UTF8.GetMaxByteCount(sig.Length); @@ -167,12 +172,10 @@ public static Guid CreateIID(Type type) Span dataSpan = data; wrt_pinterface_namespace.TryWriteBytes(dataSpan); var numBytes = UTF8Encoding.UTF8.GetBytes(sig, dataSpan[16..]); - data = data[..(16 + numBytes)]; + data = data[..(16 + numBytes)]; + + return encode_guid(SHA1.HashData(data)); #endif - using (SHA1 sha = new SHA1CryptoServiceProvider()) - { - return encode_guid(sha.ComputeHash(data)); - } } } } diff --git a/src/WinRT.Runtime/Interop/ExceptionErrorInfo.cs b/src/WinRT.Runtime/Interop/ExceptionErrorInfo.cs index 775c62b73..c2424e8c6 100644 --- a/src/WinRT.Runtime/Interop/ExceptionErrorInfo.cs +++ b/src/WinRT.Runtime/Interop/ExceptionErrorInfo.cs @@ -438,9 +438,6 @@ internal unsafe class IRestrictedErrorInfo : global::WinRT.Interop.IRestrictedEr [Guid("82BA7092-4C88-427D-A7BC-16DD93FEB67E")] public struct Vftbl { - public delegate int _GetErrorDetails(IntPtr thisPtr, out IntPtr description, out int error, out IntPtr restrictedDescription, out IntPtr capabilitySid); - public delegate int _GetReference(IntPtr thisPtr, out IntPtr reference); - internal global::WinRT.Interop.IUnknownVftbl unknownVftbl; private void* _GetErrorDetails_0; public delegate* unmanaged[Stdcall] GetErrorDetails_0 => (delegate* unmanaged[Stdcall])_GetErrorDetails_0;