// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/child/pdf_child_init.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/path_service.h" #include "chrome/common/chrome_paths.h" #include "content/public/child/child_thread.h" #if defined(OS_WIN) #include "base/win/iat_patch_function.h" #endif namespace chrome { namespace { #if defined(OS_WIN) static base::win::IATPatchFunction g_iat_patch_createdca; HDC WINAPI CreateDCAPatch(LPCSTR driver_name, LPCSTR device_name, LPCSTR output, const void* init_data) { DCHECK(std::string("DISPLAY") == std::string(driver_name)); DCHECK(!device_name); DCHECK(!output); DCHECK(!init_data); // CreateDC fails behind the sandbox, but not CreateCompatibleDC. return CreateCompatibleDC(NULL); } typedef DWORD (WINAPI* GetFontDataPtr) (HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length); GetFontDataPtr g_original_get_font_data = NULL; static base::win::IATPatchFunction g_iat_patch_get_font_data; DWORD WINAPI GetFontDataPatch(HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { int rv = g_original_get_font_data(hdc, table, offset, buffer, length); if (rv == GDI_ERROR && hdc) { HFONT font = static_cast(GetCurrentObject(hdc, OBJ_FONT)); LOGFONT logfont; if (GetObject(font, sizeof(LOGFONT), &logfont)) { std::vector font_data; if (content::ChildThread::Get()) content::ChildThread::Get()->PreCacheFont(logfont); rv = g_original_get_font_data(hdc, table, offset, buffer, length); if (content::ChildThread::Get()) content::ChildThread::Get()->ReleaseCachedFonts(); } } return rv; } #endif // OS_WIN } // namespace void InitializePDF() { #if defined(OS_WIN) // Need to patch a few functions for font loading to work correctly. This can // be removed once we switch PDF to use Skia. HMODULE current_module = NULL; wchar_t current_module_name[MAX_PATH]; CHECK(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast(InitializePDF), ¤t_module)); DWORD result = GetModuleFileNameW(current_module, current_module_name, MAX_PATH); if (!result || result == MAX_PATH) return; g_iat_patch_createdca.Patch(current_module_name, "gdi32.dll", "CreateDCA", CreateDCAPatch); g_iat_patch_get_font_data.Patch(current_module_name, "gdi32.dll", "GetFontData", GetFontDataPatch); g_original_get_font_data = reinterpret_cast( g_iat_patch_get_font_data.original_function()); #endif // OS_WIN } } // namespace chrome