Skip to content

Commit a139211

Browse files
DWM Crash Fix Backport (#11621)
1 parent 2fe8838 commit a139211

5 files changed

Lines changed: 46 additions & 6 deletions

File tree

src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/FrameworkAppContextSwitches.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,18 @@ public static bool DisableDynamicResourceOptimization
147147
return LocalAppContext.GetCachedSwitchValue(DisableDynamicResourceOptimizationSwitchName, ref _DisableDynamicResourceOptimization);
148148
}
149149
}
150+
151+
// Swtich to disable DWM crash containment
152+
internal const string DisableDWMCrashContainmentSwitchName = "Switch.System.Windows.Media.DisableDWMCrashContainment";
153+
private static int _disableDWMCrashContainment;
154+
public static bool DisableDWMCrashContainment
155+
{
156+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
157+
get
158+
{
159+
return LocalAppContext.GetCachedSwitchValue(DisableDWMCrashContainmentSwitchName, ref _disableDWMCrashContainment);
160+
}
161+
}
150162
}
151163
}
152164

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/AppContextDefaultValues.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static partial void PopulateDefaultValuesPartial(string platformIdentifier, stri
3232
LocalAppContext.DefineSwitchDefault(FrameworkAppContextSwitches.ItemAutomationPeerKeepsItsItemAliveSwitchName, false);
3333
LocalAppContext.DefineSwitchDefault(FrameworkAppContextSwitches.DisableFluentThemeWindowBackdropSwitchName, false);
3434
LocalAppContext.DefineSwitchDefault(FrameworkAppContextSwitches.DisableDynamicResourceOptimizationSwitchName, false);
35-
35+
LocalAppContext.DefineSwitchDefault(FrameworkAppContextSwitches.DisableDWMCrashContainmentSwitchName, false);
3636
#pragma warning restore CS0436 // Type conflicts with imported type
3737
}
3838
}

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Appearance/WindowBackdropManager.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ private static bool UpdateGlassFrame(IntPtr hwnd, WindowBackdropType backdropTyp
131131
margins = new MARGINS { cxLeftWidth = -1, cxRightWidth = -1, cyTopHeight = -1, cyBottomHeight = -1 };
132132
}
133133

134-
var dwmApiResult = NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref margins);
135-
return new HRESULT((uint)dwmApiResult) == HRESULT.S_OK;
134+
return NativeMethods.DwmExtendFrameIntoClientArea(hwnd, ref margins);
136135
}
137136

138137
#endregion

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,11 @@ private void _ExtendGlassFrame()
10021002
cyBottomHeight = (int)Math.Ceiling(deviceGlassThickness.Bottom),
10031003
};
10041004

1005-
NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin);
1005+
bool dwmApiResult = NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin);
1006+
if(!dwmApiResult)
1007+
{
1008+
_hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor;
1009+
}
10061010
}
10071011
}
10081012

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Standard/NativeMethods.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
using System.Runtime.InteropServices;
1010
using System.Runtime.InteropServices.ComTypes;
1111
using System.Text;
12+
using System.Threading;
1213
using Microsoft.Win32.SafeHandles;
14+
using MS.Internal;
1315

1416
// Some COM interfaces and Win32 structures are already declared in the framework.
1517
// Interesting ones to remember in System.Runtime.InteropServices.ComTypes are:
@@ -2501,8 +2503,8 @@ public static IntPtr CreateWindowEx(
25012503
[DllImport("dwmapi.dll", PreserveSig = false)]
25022504
public static extern int DwmGetWindowAttribute(IntPtr hWnd, DWMWA dwAttributeToGet, ref int pvAttributeValue, int cbAttribute);
25032505

2504-
[DllImport("dwmapi.dll", PreserveSig = false)]
2505-
public static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset);
2506+
[DllImport("dwmapi.dll", EntryPoint = "DwmExtendFrameIntoClientArea", PreserveSig = true, SetLastError = true)]
2507+
private static extern HRESULT _DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset);
25062508

25072509
[DllImport("dwmapi.dll", EntryPoint = "DwmIsCompositionEnabled", PreserveSig = false)]
25082510
[return: MarshalAs(UnmanagedType.Bool)]
@@ -2511,6 +2513,29 @@ public static IntPtr CreateWindowEx(
25112513
[DllImport("dwmapi.dll", EntryPoint = "DwmGetColorizationColor", PreserveSig = true)]
25122514
private static extern HRESULT _DwmGetColorizationColor(out uint pcrColorization, [Out, MarshalAs(UnmanagedType.Bool)] out bool pfOpaqueBlend);
25132515

2516+
public static bool DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset)
2517+
{
2518+
HRESULT hr = _DwmExtendFrameIntoClientArea(hwnd, ref pMarInset);
2519+
if(hr == HRESULT.S_OK)
2520+
{
2521+
return true;
2522+
}
2523+
2524+
if(FrameworkAppContextSwitches.DisableDWMCrashContainment)
2525+
{
2526+
// Original behavior: just call the native method and let any exceptions propagate.
2527+
HRESULT.ThrowLastError();
2528+
}
2529+
2530+
// Crash only if the arguments are invalid.
2531+
if(hr == HRESULT.E_INVALIDARG)
2532+
{
2533+
HRESULT.ThrowLastError();
2534+
}
2535+
2536+
return false;
2537+
}
2538+
25142539
public static bool DwmGetColorizationColor(out uint pcrColorization, out bool pfOpaqueBlend)
25152540
{
25162541
// Make this call safe to make on downlevel OSes...

0 commit comments

Comments
 (0)