Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: content/ppapi_plugin/ppapi_thread.cc

Issue 897563002: Unify the three places that patch font loading for PDFium on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ppapi_plugin/ppapi_thread.h" 5 #include "content/ppapi_plugin/ppapi_thread.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/cpu.h" 10 #include "base/cpu.h"
(...skipping 24 matching lines...) Expand all
35 #include "ipc/ipc_sync_channel.h" 35 #include "ipc/ipc_sync_channel.h"
36 #include "ipc/ipc_sync_message_filter.h" 36 #include "ipc/ipc_sync_message_filter.h"
37 #include "ppapi/c/dev/ppp_network_state_dev.h" 37 #include "ppapi/c/dev/ppp_network_state_dev.h"
38 #include "ppapi/c/pp_errors.h" 38 #include "ppapi/c/pp_errors.h"
39 #include "ppapi/c/ppp.h" 39 #include "ppapi/c/ppp.h"
40 #include "ppapi/proxy/interface_list.h" 40 #include "ppapi/proxy/interface_list.h"
41 #include "ppapi/proxy/plugin_globals.h" 41 #include "ppapi/proxy/plugin_globals.h"
42 #include "ppapi/proxy/plugin_message_filter.h" 42 #include "ppapi/proxy/plugin_message_filter.h"
43 #include "ppapi/proxy/ppapi_messages.h" 43 #include "ppapi/proxy/ppapi_messages.h"
44 #include "ppapi/proxy/resource_reply_thread_registrar.h" 44 #include "ppapi/proxy/resource_reply_thread_registrar.h"
45 #include "ppapi/shared_impl/proxy_lock.h"
46 #include "third_party/WebKit/public/web/WebKit.h" 45 #include "third_party/WebKit/public/web/WebKit.h"
47 #include "ui/base/ui_base_switches.h" 46 #include "ui/base/ui_base_switches.h"
48 47
49 #if defined(OS_WIN) 48 #if defined(OS_WIN)
50 #include "base/win/iat_patch_function.h"
51 #include "base/win/win_util.h" 49 #include "base/win/win_util.h"
52 #include "base/win/windows_version.h" 50 #include "base/win/windows_version.h"
53 #include "sandbox/win/src/sandbox.h" 51 #include "sandbox/win/src/sandbox.h"
54 #elif defined(OS_MACOSX) 52 #elif defined(OS_MACOSX)
55 #include "content/common/sandbox_init_mac.h" 53 #include "content/common/sandbox_init_mac.h"
56 #endif 54 #endif
57 55
58 #if defined(OS_WIN) 56 #if defined(OS_WIN)
59 const char kWidevineCdmAdapterFileName[] = "widevinecdmadapter.dll"; 57 const char kWidevineCdmAdapterFileName[] = "widevinecdmadapter.dll";
60 58
(...skipping 26 matching lines...) Expand all
87 reinterpret_cast<PfnEnumSystemLocalesEx> 85 reinterpret_cast<PfnEnumSystemLocalesEx>
88 (GetProcAddress(handle_kern32, "EnumSystemLocalesEx")); 86 (GetProcAddress(handle_kern32, "EnumSystemLocalesEx"));
89 87
90 enum_sys_locales_ex(EnumLocalesProcEx, LOCALE_WINDOWS, 0, 0); 88 enum_sys_locales_ex(EnumLocalesProcEx, LOCALE_WINDOWS, 0, 0);
91 } else { 89 } else {
92 EnumSystemLocalesW(EnumLocalesProc, LCID_INSTALLED); 90 EnumSystemLocalesW(EnumLocalesProc, LCID_INSTALLED);
93 } 91 }
94 } 92 }
95 } 93 }
96 94
97 // TODO(scottmg): http://crbug.com/448473. This code should be removed from the
98 // renderer once PDF is always OOP and/or PDF is made to use Skia instead of GDI
99 // directly.
100 const wchar_t kPdfFileName[] = L"pdf.dll";
101
102 static base::win::IATPatchFunction g_iat_patch_createdca;
103 HDC WINAPI CreateDCAPatch(LPCSTR driver_name,
104 LPCSTR device_name,
105 LPCSTR output,
106 const void* init_data) {
107 DCHECK(std::string("DISPLAY") == std::string(driver_name));
108 DCHECK(!device_name);
109 DCHECK(!output);
110 DCHECK(!init_data);
111
112 // CreateDC fails behind the sandbox, but not CreateCompatibleDC.
113 return CreateCompatibleDC(NULL);
114 }
115
116 static base::win::IATPatchFunction g_iat_patch_get_font_data;
117 DWORD WINAPI GetFontDataPatch(HDC hdc,
118 DWORD table,
119 DWORD offset,
120 LPVOID buffer,
121 DWORD length) {
122 int rv = GetFontData(hdc, table, offset, buffer, length);
123 if (rv == GDI_ERROR && hdc) {
124 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT));
125
126 LOGFONT logfont;
127 if (GetObject(font, sizeof(LOGFONT), &logfont)) {
128 std::vector<char> font_data;
129 {
130 ppapi::ProxyAutoLock lock;
131 // In the sandbox, font loading will fail. We ask the browser to load it
132 // which causes it to be loaded by the kernel, which then makes the
133 // subsequent call succeed.
134 ppapi::proxy::PluginGlobals::Get()->PreCacheFontForFlash(
135 reinterpret_cast<const void*>(&logfont));
136 }
137 rv = GetFontData(hdc, table, offset, buffer, length);
138 }
139 }
140 return rv;
141 }
142
143 #else
144 extern void* g_target_services;
145 #endif 95 #endif
146 96
147 namespace content { 97 namespace content {
148 98
149 typedef int32_t (*InitializeBrokerFunc) 99 typedef int32_t (*InitializeBrokerFunc)
150 (PP_ConnectInstance_Func* connect_instance_func); 100 (PP_ConnectInstance_Func* connect_instance_func);
151 101
152 PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker) 102 PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
153 : is_broker_(is_broker), 103 : is_broker_(is_broker),
154 connect_instance_func_(NULL), 104 connect_instance_func_(NULL),
(...skipping 11 matching lines...) Expand all
166 channel()->AddFilter( 116 channel()->AddFilter(
167 new ppapi::proxy::PluginMessageFilter( 117 new ppapi::proxy::PluginMessageFilter(
168 NULL, globals->resource_reply_thread_registrar())); 118 NULL, globals->resource_reply_thread_registrar()));
169 } 119 }
170 } 120 }
171 121
172 PpapiThread::~PpapiThread() { 122 PpapiThread::~PpapiThread() {
173 } 123 }
174 124
175 void PpapiThread::Shutdown() { 125 void PpapiThread::Shutdown() {
176 ChildThread::Shutdown(); 126 ChildThreadImpl::Shutdown();
177 127
178 ppapi::proxy::PluginGlobals::Get()->ResetPluginProxyDelegate(); 128 ppapi::proxy::PluginGlobals::Get()->ResetPluginProxyDelegate();
179 if (plugin_entry_points_.shutdown_module) 129 if (plugin_entry_points_.shutdown_module)
180 plugin_entry_points_.shutdown_module(); 130 plugin_entry_points_.shutdown_module();
181 blink_platform_impl_->Shutdown(); 131 blink_platform_impl_->Shutdown();
182 blink::shutdown(); 132 blink::shutdown();
183 } 133 }
184 134
185 bool PpapiThread::Send(IPC::Message* msg) { 135 bool PpapiThread::Send(IPC::Message* msg) {
186 // Allow access from multiple threads. 136 // Allow access from multiple threads.
187 if (base::MessageLoop::current() == message_loop()) 137 if (base::MessageLoop::current() == message_loop())
188 return ChildThread::Send(msg); 138 return ChildThreadImpl::Send(msg);
189 139
190 return sync_message_filter()->Send(msg); 140 return sync_message_filter()->Send(msg);
191 } 141 }
192 142
193 // Note that this function is called only for messages from the channel to the 143 // Note that this function is called only for messages from the channel to the
194 // browser process. Messages from the renderer process are sent via a different 144 // browser process. Messages from the renderer process are sent via a different
195 // channel that ends up at Dispatcher::OnMessageReceived. 145 // channel that ends up at Dispatcher::OnMessageReceived.
196 bool PpapiThread::OnControlMessageReceived(const IPC::Message& msg) { 146 bool PpapiThread::OnControlMessageReceived(const IPC::Message& msg) {
197 bool handled = true; 147 bool handled = true;
198 IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg) 148 IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
199 IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnLoadPlugin) 149 IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnLoadPlugin)
200 IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnCreateChannel) 150 IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnCreateChannel)
201 IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnSetNetworkState) 151 IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnSetNetworkState)
202 IPC_MESSAGE_HANDLER(PpapiMsg_Crash, OnCrash) 152 IPC_MESSAGE_HANDLER(PpapiMsg_Crash, OnCrash)
203 IPC_MESSAGE_HANDLER(PpapiMsg_Hang, OnHang) 153 IPC_MESSAGE_HANDLER(PpapiMsg_Hang, OnHang)
204 IPC_MESSAGE_UNHANDLED(handled = false) 154 IPC_MESSAGE_UNHANDLED(handled = false)
205 IPC_END_MESSAGE_MAP() 155 IPC_END_MESSAGE_MAP()
206 return handled; 156 return handled;
207 } 157 }
208 158
209 void PpapiThread::OnChannelConnected(int32 peer_pid) { 159 void PpapiThread::OnChannelConnected(int32 peer_pid) {
210 ChildThread::OnChannelConnected(peer_pid); 160 ChildThreadImpl::OnChannelConnected(peer_pid);
211 #if defined(OS_WIN) 161 #if defined(OS_WIN)
212 if (is_broker_) 162 if (is_broker_)
213 peer_handle_.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, peer_pid)); 163 peer_handle_.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, peer_pid));
214 #endif 164 #endif
215 } 165 }
216 166
217 base::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() { 167 base::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() {
218 return ChildProcess::current()->io_message_loop_proxy(); 168 return ChildProcess::current()->io_message_loop_proxy();
219 } 169 }
220 170
(...skipping 25 matching lines...) Expand all
246 return this; 196 return this;
247 } 197 }
248 198
249 std::string PpapiThread::GetUILanguage() { 199 std::string PpapiThread::GetUILanguage() {
250 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 200 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
251 return command_line->GetSwitchValueASCII(switches::kLang); 201 return command_line->GetSwitchValueASCII(switches::kLang);
252 } 202 }
253 203
254 void PpapiThread::PreCacheFont(const void* logfontw) { 204 void PpapiThread::PreCacheFont(const void* logfontw) {
255 #if defined(OS_WIN) 205 #if defined(OS_WIN)
256 Send(new ChildProcessHostMsg_PreCacheFont( 206 ChildThreadImpl::PreCacheFont(*static_cast<const LOGFONTW*>(logfontw));
257 *static_cast<const LOGFONTW*>(logfontw)));
258 #endif 207 #endif
259 } 208 }
260 209
261 void PpapiThread::SetActiveURL(const std::string& url) { 210 void PpapiThread::SetActiveURL(const std::string& url) {
262 GetContentClient()->SetActiveURL(GURL(url)); 211 GetContentClient()->SetActiveURL(GURL(url));
263 } 212 }
264 213
265 PP_Resource PpapiThread::CreateBrowserFont( 214 PP_Resource PpapiThread::CreateBrowserFont(
266 ppapi::proxy::Connection connection, 215 ppapi::proxy::Connection connection,
267 PP_Instance instance, 216 PP_Instance instance,
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 return; 316 return;
368 } 317 }
369 } 318 }
370 } 319 }
371 320
372 #if defined(OS_WIN) 321 #if defined(OS_WIN)
373 // If code subsequently tries to exit using abort(), force a crash (since 322 // If code subsequently tries to exit using abort(), force a crash (since
374 // otherwise these would be silent terminations and fly under the radar). 323 // otherwise these would be silent terminations and fly under the radar).
375 base::win::SetAbortBehaviorForCrashReporting(); 324 base::win::SetAbortBehaviorForCrashReporting();
376 325
377 // Need to patch a few functions for font loading to work correctly. This can
378 // be removed once we switch PDF to use Skia.
379 if (GetModuleHandle(kPdfFileName)) {
380 g_iat_patch_createdca.Patch(kPdfFileName, "gdi32.dll", "CreateDCA",
381 CreateDCAPatch);
382 g_iat_patch_get_font_data.Patch(kPdfFileName, "gdi32.dll", "GetFontData",
383 GetFontDataPatch);
384 }
385
386 // Once we lower the token the sandbox is locked down and no new modules 326 // Once we lower the token the sandbox is locked down and no new modules
387 // can be loaded. TODO(cpu): consider changing to the loading style of 327 // can be loaded. TODO(cpu): consider changing to the loading style of
388 // regular plugins. 328 // regular plugins.
389 if (g_target_services) { 329 if (g_target_services) {
390 // Let Flash and Widevine CDM adapter load DXVA before lockdown on Vista+. 330 // Let Flash and Widevine CDM adapter load DXVA before lockdown on Vista+.
391 if (permissions.HasPermission(ppapi::PERMISSION_FLASH) || 331 if (permissions.HasPermission(ppapi::PERMISSION_FLASH) ||
392 path.BaseName().MaybeAsASCII() == kWidevineCdmAdapterFileName) { 332 path.BaseName().MaybeAsASCII() == kWidevineCdmAdapterFileName) {
393 if (base::win::OSInfo::GetInstance()->version() >= 333 if (base::win::OSInfo::GetInstance()->version() >=
394 base::win::VERSION_VISTA) { 334 base::win::VERSION_VISTA) {
395 LoadLibraryA("dxva2.dll"); 335 LoadLibraryA("dxva2.dll");
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 std::string("Plugin.Ppapi") + (is_broker_ ? "Broker" : "Plugin") + 540 std::string("Plugin.Ppapi") + (is_broker_ ? "Broker" : "Plugin") +
601 "LoadErrorCode_" + path.BaseName().MaybeAsASCII(); 541 "LoadErrorCode_" + path.BaseName().MaybeAsASCII();
602 542
603 // For sparse histograms, we can use the macro, as it does not incorporate a 543 // For sparse histograms, we can use the macro, as it does not incorporate a
604 // static. 544 // static.
605 UMA_HISTOGRAM_SPARSE_SLOWLY(histogram_name, error.code); 545 UMA_HISTOGRAM_SPARSE_SLOWLY(histogram_name, error.code);
606 #endif 546 #endif
607 } 547 }
608 548
609 } // namespace content 549 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698