Bug 1701770 - Defer Windows DPI Awareness from load time to run time r=bobowen,aklotz

Currently, we set DPI awareness in the manifest files for firefox.exe.

Unfortunately, that causes DPI-related Win32k calls when user32.dll
is loaded.

This changes things to wait until we are sure we're not running in a
Win32k Lockdown Content Process before we attempt to initialize DPI scaling.

Differential Revision: https://phabricator.services.mozilla.com/D116433
This commit is contained in:
Chris Martin 2021-06-21 13:50:31 +00:00
Родитель 06ed013306
Коммит 38d538c966
5 изменённых файлов: 156 добавлений и 6 удалений

Просмотреть файл

@ -36,12 +36,6 @@
</ms_asmv3:requestedPrivileges>
</ms_asmv3:security>
</ms_asmv3:trustInfo>
<ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
</ms_asmv3:windowsSettings>
</ms_asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>

Просмотреть файл

@ -28,6 +28,7 @@
# include "freestanding/SharedSection.h"
# include "LauncherProcessWin.h"
# include "mozilla/WindowsDllBlocklist.h"
# include "mozilla/WindowsDpiInitialization.h"
# define XRE_WANT_ENVIRON
# define strcasecmp _stricmp
@ -296,6 +297,19 @@ int main(int argc, char* argv[], char* envp[]) {
DllBlocklist_Initialize(gBlocklistInitFlags |
eDllBlocklistInitFlagIsChildProcess);
# endif
# if defined(XP_WIN)
// Ideally, we would be able to set our DPI awareness in
// firefox.exe.manifest Unfortunately, that would cause Win32k calls when
// user32.dll gets loaded, which would be incompatible with Win32k Lockdown
//
// MSDN says that it's allowed-but-not-recommended to initialize DPI
// programatically, as long as it's done before any HWNDs are created.
// Thus, we do it almost as soon as we possibly can
{
auto result = mozilla::WindowsDpiInitialization();
(void)result; // Ignore errors since some tools block DPI calls
}
# endif
# if defined(XP_WIN) && defined(MOZ_SANDBOX)
// We need to initialize the sandbox TargetServices before InitXPCOMGlue
// because we might need the sandbox broker to give access to some files.
@ -328,6 +342,19 @@ int main(int argc, char* argv[], char* envp[]) {
#endif
#if defined(XP_WIN)
// Ideally, we would be able to set our DPI awareness in firefox.exe.manifest
// Unfortunately, that would cause Win32k calls when user32.dll gets loaded,
// which would be incompatible with Win32k Lockdown
//
// MSDN says that it's allowed-but-not-recommended to initialize DPI
// programatically, as long as it's done before any HWNDs are created.
// Thus, we do it almost as soon as we possibly can
{
auto result = mozilla::WindowsDpiInitialization();
(void)result; // Ignore errors since some tools block DPI calls
}
// Once the browser process hits the main function, we no longer need
// a writable section handle because all dependent modules have been
// loaded.

Просмотреть файл

@ -0,0 +1,73 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/WindowsDpiInitialization.h"
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
#include "mozilla/WindowsProcessMitigations.h"
#include "mozilla/WindowsVersion.h"
#include <shellscalingapi.h>
#include <windows.h>
namespace mozilla {
typedef HRESULT(WINAPI* SetProcessDpiAwarenessType)(PROCESS_DPI_AWARENESS);
typedef BOOL(WINAPI* SetProcessDpiAwarenessContextType)(DPI_AWARENESS_CONTEXT);
WindowsDpiInitializationResult WindowsDpiInitialization() {
// DPI Awareness can't be used in a Win32k Lockdown process, so there's
// nothing to do
if (IsWin32kLockedDown()) {
return WindowsDpiInitializationResult::Success;
}
// From MSDN:
// SetProcessDpiAwarenessContext() was added in the Win10 Anniversary Update
// SetProcessDpiAwareness() was added in Windows 8.1
// SetProcessDpiAware() was added in Windows Vista
//
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 wasn't added later until
// the Creators Update, so if it fails we just fall back to
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
if (IsWin10AnniversaryUpdateOrLater()) {
DynamicallyLinkedFunctionPtr<SetProcessDpiAwarenessContextType>
setProcessDpiAwarenessContext(L"user32.dll",
"SetProcessDpiAwarenessContext");
if (!setProcessDpiAwarenessContext) {
return WindowsDpiInitializationResult::
FindSetProcessDpiAwarenessContextFailed;
}
if (!setProcessDpiAwarenessContext(
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) &&
!setProcessDpiAwarenessContext(
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) {
return WindowsDpiInitializationResult::
SetProcessDpiAwarenessContextFailed;
}
return WindowsDpiInitializationResult::Success;
} else if (IsWin8Point1OrLater()) {
DynamicallyLinkedFunctionPtr<SetProcessDpiAwarenessType>
setProcessDpiAwareness(L"Shcore.dll", "SetProcessDpiAwareness");
if (!setProcessDpiAwareness) {
return WindowsDpiInitializationResult::FindSetProcessDpiAwarenessFailed;
}
if (FAILED(setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE))) {
return WindowsDpiInitializationResult::SetProcessDpiAwarenessFailed;
}
return WindowsDpiInitializationResult::Success;
} else {
if (!SetProcessDPIAware()) {
return WindowsDpiInitializationResult::SetProcessDPIAwareFailed;
}
return WindowsDpiInitializationResult::Success;
}
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_MOZGLUE_MISC_WINDOWSDPIINITIALIZATION_H_
#define MOZILLA_MOZGLUE_MISC_WINDOWSDPIINITIALIZATION_H_
#include "mozilla/Types.h"
namespace mozilla {
// The result codes that may be returned from WindowsDpiInitialization()
enum class WindowsDpiInitializationResult : uint32_t {
Success,
FindSetProcessDpiAwarenessContextFailed,
SetProcessDpiAwarenessContextFailed,
FindSetProcessDpiAwarenessFailed,
SetProcessDpiAwarenessFailed,
SetProcessDPIAwareFailed,
};
// Get a string representation of any WindowsDpiInitializationResult value
inline const char* WindowsDpiInitializationResultString(
WindowsDpiInitializationResult result) {
switch (result) {
case WindowsDpiInitializationResult::Success:
return "Success";
case WindowsDpiInitializationResult::
FindSetProcessDpiAwarenessContextFailed:
return "Failed to find SetProcessDpiAwarenessContext";
case WindowsDpiInitializationResult::SetProcessDpiAwarenessContextFailed:
return "SetProcessDpiAwarenessContext failed";
case WindowsDpiInitializationResult::FindSetProcessDpiAwarenessFailed:
return "Failed to find SetProcessDpiAwareness";
case WindowsDpiInitializationResult::SetProcessDpiAwarenessFailed:
return "SetProcessDpiAwareness failed";
case WindowsDpiInitializationResult::SetProcessDPIAwareFailed:
return "SetProcessDPIAware failed";
default:
return "Unknown result";
}
}
// Initialize DPI awareness to the best available for the current OS
// According to MSDN, this will be:
// Per-Monitor V2 for Windows 10 Creators Update (1703) and later
// Per-Monitor V1 for Windows 8.1 and later
// System DPI for Vista and later (we don't support anything older)
// https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
MFBT_API WindowsDpiInitializationResult WindowsDpiInitialization();
} // namespace mozilla
#endif // MOZILLA_MOZGLUE_MISC_WINDOWSDPIINITIALIZATION_H_

Просмотреть файл

@ -59,6 +59,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
"DynamicallyLinkedFunctionPtr.h",
"ImportDir.h",
"NativeNt.h",
"WindowsDpiInitialization.h",
"WindowsEnumProcessModules.h",
"WindowsMapRemoteView.h",
"WindowsProcessMitigations.h",
@ -69,6 +70,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
SOURCES += [
"PreXULSkeletonUI.cpp",
"TimeStamp_windows.cpp",
"WindowsDpiInitialization.cpp",
"WindowsMapRemoteView.cpp",
"WindowsProcessMitigations.cpp",
"WindowsUnicode.cpp",