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 |