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 |
99 // Windows-only DirectWrite support. These warm up the DirectWrite paths | 149 // Windows-only DirectWrite support. These warm up the DirectWrite paths |
100 // before sandbox lock down to allow Skia access to the Font Manager service. | 150 // before sandbox lock down to allow Skia access to the Font Manager service. |
101 void CreateDirectWriteFactory(IDWriteFactory** factory) { | 151 void CreateDirectWriteFactory(IDWriteFactory** factory) { |
102 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; | 152 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; |
103 HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll"); | 153 HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll"); |
104 // TODO(scottmg): Temporary code to track crash in http://crbug.com/387867. | 154 // TODO(scottmg): Temporary code to track crash in http://crbug.com/387867. |
105 if (!dwrite_dll) { | 155 if (!dwrite_dll) { |
106 DWORD load_library_get_last_error = GetLastError(); | 156 DWORD load_library_get_last_error = GetLastError(); |
107 base::debug::Alias(&dwrite_dll); | 157 base::debug::Alias(&dwrite_dll); |
108 base::debug::Alias(&load_library_get_last_error); | 158 base::debug::Alias(&load_library_get_last_error); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 DoSingleGdiPatch(create_enum_font_families_patch_, path, | 454 DoSingleGdiPatch(create_enum_font_families_patch_, path, |
405 "EnumFontFamiliesExW", EnumFontFamiliesExWPatch); | 455 "EnumFontFamiliesExW", EnumFontFamiliesExWPatch); |
406 DoSingleGdiPatch(create_get_font_data_patch_, path, "GetFontData", | 456 DoSingleGdiPatch(create_get_font_data_patch_, path, "GetFontData", |
407 GetFontDataPatch); | 457 GetFontDataPatch); |
408 DoSingleGdiPatch(create_select_object_patch_, path, "SelectObject", | 458 DoSingleGdiPatch(create_select_object_patch_, path, "SelectObject", |
409 SelectObjectPatch); | 459 SelectObjectPatch); |
410 } | 460 } |
411 | 461 |
412 } // namespace | 462 } // namespace |
413 | 463 |
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 |