Commit df38f6b9 authored by Lei Zhang's avatar Lei Zhang Committed by Commit Bot

Fix gdi32 GetFontData() patching for printing.

On Windows, GetFontData() calls from within sandboxed processes have to
use the font_cache mechanism to work correctly. This requires a
correctly patched GetFontData(), which broke in M76.

https://crbug.com/980577 broke Import Address Table patching for
gdi32.dll. This eventually got fixed, but the final fix in
https://crrev.com/686696 tried to minimize the amount of patching
necessary, and did not get it 100% correct for printing use cases.  As
a result, sometimes utility processes used for printing did not get
patched. This fix by patching utility processes in InitializePDF().
Rearrange the function and update comments along the way.

The font_cache mechanism in the Cloud Print service process also broke
around the same time due to https://crrev.com/660952, but that just got
fixed in https://crrev.com/700317.

Bug: 1005867
Change-Id: I0bb691d8208fbbb9bf885767a959119a388def09
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1826197Reviewed-by: default avatarKen Rockot <rockot@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700918}
parent d0b11f73
...@@ -52,39 +52,46 @@ void InitializePDF() { ...@@ -52,39 +52,46 @@ void InitializePDF() {
#if defined(OS_WIN) #if defined(OS_WIN)
const base::CommandLine& command_line = const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess(); *base::CommandLine::ForCurrentProcess();
std::string process_type = const std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType); command_line.GetSwitchValueASCII(switches::kProcessType);
bool is_pdf_utility_process = false;
if (command_line.HasSwitch(service_manager::switches::kServiceSandboxType)) { // Patch utility processes, which includes ones that do PDF to EMF conversion.
// They are hard to differentiate because they can also be launched from
// chrome/service/ in a different manner vs. from chrome/browser/.
bool needs_gdi32_patching = process_type == switches::kUtilityProcess;
if (!needs_gdi32_patching) {
// Windows prior to Win10 use GDI fonts in the PDF PPAPI process.
needs_gdi32_patching = process_type == switches::kPpapiPluginProcess &&
base::win::GetVersion() < base::win::Version::WIN10;
}
if (!needs_gdi32_patching) {
// Printing uses GDI for fonts on all versions of Windows.
// TODO(thestig): Check and see if this is actually necessary.
std::string service_sandbox_type = command_line.GetSwitchValueASCII( std::string service_sandbox_type = command_line.GetSwitchValueASCII(
service_manager::switches::kServiceSandboxType); service_manager::switches::kServiceSandboxType);
if (service_sandbox_type == needs_gdi32_patching = service_sandbox_type ==
service_manager::switches::kPdfCompositorSandbox) { service_manager::switches::kPdfCompositorSandbox;
is_pdf_utility_process = true;
}
} }
// On Win10, pdf does not use GDI fonts and does not need to run this
// initialization for the ppapi process. Printing does still use GDI for if (!needs_gdi32_patching)
// fonts on Win10 though. return;
if (is_pdf_utility_process ||
(process_type == switches::kPpapiPluginProcess &&
base::win::GetVersion() < base::win::Version::WIN10)) {
// Need to patch a few functions for font loading to work correctly. This
// can be removed once we switch PDF to use Skia
// (https://bugs.chromium.org/p/pdfium/issues/detail?id=11).
#if defined(COMPONENT_BUILD) #if defined(COMPONENT_BUILD)
HMODULE module = ::GetModuleHandleA("pdfium.dll"); HMODULE module = ::GetModuleHandleA("pdfium.dll");
DCHECK(module); DCHECK(module);
#else #else
HMODULE module = CURRENT_MODULE(); HMODULE module = CURRENT_MODULE();
#endif // defined(COMPONENT_BUILD) #endif // defined(COMPONENT_BUILD)
static base::NoDestructor<base::win::IATPatchFunction> patch_get_font_data; // Need to patch GetFontData() for font loading to work correctly. This can be
patch_get_font_data->PatchFromModule( // removed once PDFium switches to use Skia. https://crbug.com/pdfium/11
module, "gdi32.dll", "GetFontData", static base::NoDestructor<base::win::IATPatchFunction> patch_get_font_data;
reinterpret_cast<void*>(GetFontDataPatch)); patch_get_font_data->PatchFromModule(
g_original_get_font_data = reinterpret_cast<GetFontDataPtr>( module, "gdi32.dll", "GetFontData",
patch_get_font_data->original_function()); reinterpret_cast<void*>(GetFontDataPatch));
} g_original_get_font_data = reinterpret_cast<GetFontDataPtr>(
patch_get_font_data->original_function());
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment