Add public implementation WindowsRuntime ExceptionSupport (dotnet/coreclr#18494)
authorLuqun Lou <luqunl@users.noreply.github.com>
Mon, 18 Jun 2018 20:24:48 +0000 (13:24 -0700)
committerJan Kotas <jkotas@microsoft.com>
Mon, 18 Jun 2018 20:24:48 +0000 (13:24 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/d4bbfb39572a2e1cb0708c7c94d0c05aee69d813

src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs [new file with mode: 0644]
src/coreclr/src/System.Private.CoreLib/src/System/Exception.cs
src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs

index 419d1cc..a97fa08 100644 (file)
     <Compile Include="$(BclSourcesRoot)\Internal\Runtime\Augments\RuntimeThread.cs" />
     <Compile Include="$(BclSourcesRoot)\Internal\Console.cs" />
     <Compile Condition="'$(FeatureCominterop)' == 'true'"  Include="$(BclSourcesRoot)\Internal\Threading\Tasks\AsyncCausalitySupport.cs" />
+    <Compile Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\Internal\Runtime\InteropServices\WindowsRuntime\ExceptionSupport.cs" />
     <Compile Condition="'$(FeatureAppX)' == 'true'" Include="$(BclSourcesRoot)\Internal\Resources\WindowsRuntimeResourceManagerBase.cs" />
     <Compile Condition="'$(FeatureAppX)' == 'true'" Include="$(BclSourcesRoot)\Internal\Resources\PRIExceptionInfo.cs" />
   </ItemGroup>
diff --git a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs
new file mode 100644 (file)
index 0000000..1772105
--- /dev/null
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices.WindowsRuntime;
+
+namespace Internal.Runtime.InteropServices.WindowsRuntime
+{
+    public static class ExceptionSupport
+    {
+        /// <summary>
+        /// Attach restricted error information to the exception if it may apply to that exception, returning
+        /// back the input value
+        /// </summary>
+        public static Exception AttachRestrictedErrorInfo(Exception e)
+        {
+            // If there is no exception, then the restricted error info doesn't apply to it
+            if (e != null)
+            {
+                try
+                {
+                    // Get the restricted error info for this thread and see if it may correlate to the current
+                    // exception object.  Note that in general the thread's IRestrictedErrorInfo is not meant for
+                    // exceptions that are marshaled Windows.Foundation.HResults and instead are intended for
+                    // 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.
+                    IRestrictedErrorInfo restrictedErrorInfo = UnsafeNativeMethods.GetRestrictedErrorInfo();
+                    if (restrictedErrorInfo != null)
+                    {
+                        string description;
+                        string restrictedDescription;
+                        string capabilitySid;
+                        int restrictedErrorInfoHResult;
+                        restrictedErrorInfo.GetErrorDetails(out description,
+                                                            out restrictedErrorInfoHResult,
+                                                            out restrictedDescription,
+                                                            out capabilitySid);
+
+                        // Since this is a special case where by convention there may be a correlation, there is not a
+                        // guarantee that the restricted error info does belong to the async error code.  In order to
+                        // reduce the risk that we associate incorrect information with the exception object, we need
+                        // to apply a heuristic where we attempt to match the current exception's HRESULT with the
+                        // HRESULT the IRestrictedErrorInfo belongs to.  If it is a match we will assume association
+                        // for the IAsyncInfo case.
+                        if (e.HResult == restrictedErrorInfoHResult)
+                        {
+                            string errorReference;
+                            restrictedErrorInfo.GetReference(out errorReference);
+
+                            e.AddExceptionDataForRestrictedErrorInfo(restrictedDescription,
+                                                                     errorReference,
+                                                                     capabilitySid,
+                                                                     restrictedErrorInfo);
+                        }
+                    }
+                }
+                catch
+                {
+                    // If we can't get the restricted error info, then proceed as if it isn't associated with this
+                    // error.
+                }
+            }
+
+            return e;
+        }
+
+        /// <summary>
+        /// Report that an exception has occurred which went user unhandled.  This allows the global error handler
+        /// for the application to be invoked to process the error.
+        /// </summary>
+        /// <returns>true if the error was reported, false if not (ie running on Win8)</returns>
+        public static bool ReportUnhandledError(Exception ex)
+        {
+           return WindowsRuntimeMarshal.ReportUnhandledError(ex); 
+        }
+    }
+}
index daa687d..3ba1fdc 100644 (file)
@@ -183,7 +183,6 @@ namespace System
             }
         }
 
-        // [FriendAccessAllowed]
         internal void AddExceptionDataForRestrictedErrorInfo(
             string restrictedError,
             string restrictedErrorReference,
index 521ad9d..7a4fef5 100644 (file)
@@ -1122,7 +1122,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
         /// for the application to be invoked to process the error.
         /// </summary>
         /// <returns>true if the error was reported, false if not (ie running on Win8)</returns>
-        // [FriendAccessAllowed]
         internal static bool ReportUnhandledError(Exception e)
         {
             // Only report to the WinRT global exception handler in modern apps