| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/font_warmup_win.h" | 5 #include "content/common/font_warmup_win.h" |
| 6 | 6 |
| 7 #include <dwrite.h> | 7 #include <dwrite.h> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 DWORD flags, | 89 DWORD flags, |
| 90 void* server_sid, | 90 void* server_sid, |
| 91 void* message, | 91 void* message, |
| 92 DWORD* buffer_length, | 92 DWORD* buffer_length, |
| 93 void* out_message_attributes, | 93 void* out_message_attributes, |
| 94 void* in_message_attributes, | 94 void* in_message_attributes, |
| 95 void* time_out) { | 95 void* time_out) { |
| 96 return STATUS_ACCESS_DENIED; | 96 return STATUS_ACCESS_DENIED; |
| 97 } | 97 } |
| 98 | 98 |
| 99 // Directwrite connects to the font cache service to retrieve information about | |
| 100 // fonts installed on the system etc. This works well outside the sandbox and | |
| 101 // within the sandbox as long as the lpc connection maintained by the current | |
| 102 // process with the font cache service remains valid. It appears that there | |
| 103 // are cases when this connection is dropped after which directwrite is unable | |
| 104 // to connect to the font cache service which causes problems with characters | |
| 105 // disappearing. | |
| 106 // Directwrite has fallback code to enumerate fonts if it is unable to connect | |
| 107 // to the font cache service. We need to intercept the following APIs to | |
| 108 // ensure that it does not connect to the font cache service. | |
| 109 // NtALpcConnectPort | |
| 110 // OpenSCManagerW | |
| 111 // OpenServiceW | |
| 112 // StartServiceW | |
| 113 // CloseServiceHandle. | |
| 114 // These are all IAT patched. | |
| 115 void PatchServiceManagerCalls() { | |
| 116 static bool is_patched = false; | |
| 117 if (is_patched) | |
| 118 return; | |
| 119 const char* service_provider_dll = | |
| 120 (base::win::GetVersion() >= base::win::VERSION_WIN8 | |
| 121 ? "api-ms-win-service-management-l1-1-0.dll" | |
| 122 : "advapi32.dll"); | |
| 123 | |
| 124 is_patched = true; | |
| 125 | |
| 126 DWORD patched = | |
| 127 g_iat_patch_open_sc_manager.Patch(L"dwrite.dll", service_provider_dll, | |
| 128 "OpenSCManagerW", OpenSCManagerWPatch); | |
| 129 DCHECK(patched == 0); | |
| 130 | |
| 131 patched = g_iat_patch_close_service_handle.Patch( | |
| 132 L"dwrite.dll", service_provider_dll, "CloseServiceHandle", | |
| 133 CloseServiceHandlePatch); | |
| 134 DCHECK(patched == 0); | |
| 135 | |
| 136 patched = g_iat_patch_open_service.Patch(L"dwrite.dll", service_provider_dll, | |
| 137 "OpenServiceW", OpenServiceWPatch); | |
| 138 DCHECK(patched == 0); | |
| 139 | |
| 140 patched = g_iat_patch_start_service.Patch( | |
| 141 L"dwrite.dll", service_provider_dll, "StartServiceW", StartServiceWPatch); | |
| 142 DCHECK(patched == 0); | |
| 143 | |
| 144 patched = g_iat_patch_nt_connect_port.Patch( | |
| 145 L"dwrite.dll", "ntdll.dll", "NtAlpcConnectPort", NtALpcConnectPortPatch); | |
| 146 DCHECK(patched == 0); | |
| 147 } | |
| 148 | |
| 149 // Windows-only DirectWrite support. These warm up the DirectWrite paths | 99 // Windows-only DirectWrite support. These warm up the DirectWrite paths |
| 150 // before sandbox lock down to allow Skia access to the Font Manager service. | 100 // before sandbox lock down to allow Skia access to the Font Manager service. |
| 151 void CreateDirectWriteFactory(IDWriteFactory** factory) { | 101 void CreateDirectWriteFactory(IDWriteFactory** factory) { |
| 152 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; | 102 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; |
| 153 HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll"); | 103 HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll"); |
| 154 // TODO(scottmg): Temporary code to track crash in http://crbug.com/387867. | 104 // TODO(scottmg): Temporary code to track crash in http://crbug.com/387867. |
| 155 if (!dwrite_dll) { | 105 if (!dwrite_dll) { |
| 156 DWORD load_library_get_last_error = GetLastError(); | 106 DWORD load_library_get_last_error = GetLastError(); |
| 157 base::debug::Alias(&dwrite_dll); | 107 base::debug::Alias(&dwrite_dll); |
| 158 base::debug::Alias(&load_library_get_last_error); | 108 base::debug::Alias(&load_library_get_last_error); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 DoSingleGdiPatch(create_enum_font_families_patch_, path, | 404 DoSingleGdiPatch(create_enum_font_families_patch_, path, |
| 455 "EnumFontFamiliesExW", EnumFontFamiliesExWPatch); | 405 "EnumFontFamiliesExW", EnumFontFamiliesExWPatch); |
| 456 DoSingleGdiPatch(create_get_font_data_patch_, path, "GetFontData", | 406 DoSingleGdiPatch(create_get_font_data_patch_, path, "GetFontData", |
| 457 GetFontDataPatch); | 407 GetFontDataPatch); |
| 458 DoSingleGdiPatch(create_select_object_patch_, path, "SelectObject", | 408 DoSingleGdiPatch(create_select_object_patch_, path, "SelectObject", |
| 459 SelectObjectPatch); | 409 SelectObjectPatch); |
| 460 } | 410 } |
| 461 | 411 |
| 462 } // namespace | 412 } // namespace |
| 463 | 413 |
| 414 // Directwrite connects to the font cache service to retrieve information about |
| 415 // fonts installed on the system etc. This works well outside the sandbox and |
| 416 // within the sandbox as long as the lpc connection maintained by the current |
| 417 // process with the font cache service remains valid. It appears that there |
| 418 // are cases when this connection is dropped after which directwrite is unable |
| 419 // to connect to the font cache service which causes problems with characters |
| 420 // disappearing. |
| 421 // Directwrite has fallback code to enumerate fonts if it is unable to connect |
| 422 // to the font cache service. We need to intercept the following APIs to |
| 423 // ensure that it does not connect to the font cache service. |
| 424 // NtALpcConnectPort |
| 425 // OpenSCManagerW |
| 426 // OpenServiceW |
| 427 // StartServiceW |
| 428 // CloseServiceHandle. |
| 429 // These are all IAT patched. |
| 430 void PatchServiceManagerCalls() { |
| 431 static bool is_patched = false; |
| 432 if (is_patched) |
| 433 return; |
| 434 const char* service_provider_dll = |
| 435 (base::win::GetVersion() >= base::win::VERSION_WIN8 |
| 436 ? "api-ms-win-service-management-l1-1-0.dll" |
| 437 : "advapi32.dll"); |
| 438 |
| 439 is_patched = true; |
| 440 |
| 441 DWORD patched = |
| 442 g_iat_patch_open_sc_manager.Patch(L"dwrite.dll", service_provider_dll, |
| 443 "OpenSCManagerW", OpenSCManagerWPatch); |
| 444 DCHECK(patched == 0); |
| 445 |
| 446 patched = g_iat_patch_close_service_handle.Patch( |
| 447 L"dwrite.dll", service_provider_dll, "CloseServiceHandle", |
| 448 CloseServiceHandlePatch); |
| 449 DCHECK(patched == 0); |
| 450 |
| 451 patched = g_iat_patch_open_service.Patch(L"dwrite.dll", service_provider_dll, |
| 452 "OpenServiceW", OpenServiceWPatch); |
| 453 DCHECK(patched == 0); |
| 454 |
| 455 patched = g_iat_patch_start_service.Patch( |
| 456 L"dwrite.dll", service_provider_dll, "StartServiceW", StartServiceWPatch); |
| 457 DCHECK(patched == 0); |
| 458 |
| 459 patched = g_iat_patch_nt_connect_port.Patch( |
| 460 L"dwrite.dll", "ntdll.dll", "NtAlpcConnectPort", NtALpcConnectPortPatch); |
| 461 DCHECK(patched == 0); |
| 462 } |
| 463 |
| 464 void DoPreSandboxWarmupForTypeface(SkTypeface* typeface) { | 464 void DoPreSandboxWarmupForTypeface(SkTypeface* typeface) { |
| 465 SkPaint paint_warmup; | 465 SkPaint paint_warmup; |
| 466 paint_warmup.setTypeface(typeface); | 466 paint_warmup.setTypeface(typeface); |
| 467 wchar_t glyph = L'S'; | 467 wchar_t glyph = L'S'; |
| 468 paint_warmup.measureText(&glyph, 2); | 468 paint_warmup.measureText(&glyph, 2); |
| 469 } | 469 } |
| 470 | 470 |
| 471 SkFontMgr* GetPreSandboxWarmupFontMgr() { | 471 SkFontMgr* GetPreSandboxWarmupFontMgr() { |
| 472 if (!g_warmup_fontmgr) { | 472 if (!g_warmup_fontmgr) { |
| 473 IDWriteFactory* factory; | 473 IDWriteFactory* factory; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 // down for the CC HUD code, so use the same one here. Note that we don't use | 512 // down for the CC HUD code, so use the same one here. Note that we don't use |
| 513 // a monospace as would be nice in an attempt to avoid a small startup time | 513 // a monospace as would be nice in an attempt to avoid a small startup time |
| 514 // regression, see http://crbug.com/463613. | 514 // regression, see http://crbug.com/463613. |
| 515 skia::RefPtr<SkTypeface> hud_typeface = skia::AdoptRef( | 515 skia::RefPtr<SkTypeface> hud_typeface = skia::AdoptRef( |
| 516 GetPreSandboxWarmupFontMgr()->legacyCreateTypeface("Times New Roman", 0)); | 516 GetPreSandboxWarmupFontMgr()->legacyCreateTypeface("Times New Roman", 0)); |
| 517 DoPreSandboxWarmupForTypeface(hud_typeface.get()); | 517 DoPreSandboxWarmupForTypeface(hud_typeface.get()); |
| 518 gfx::SetHudTypeface(hud_typeface); | 518 gfx::SetHudTypeface(hud_typeface); |
| 519 } | 519 } |
| 520 | 520 |
| 521 } // namespace content | 521 } // namespace content |
| OLD | NEW |