OLD | NEW |
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 "chrome/utility/chrome_content_utility_client.h" | 5 #include "chrome/utility/chrome_content_utility_client.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" |
10 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
11 #include "base/json/json_reader.h" | 12 #include "base/json/json_reader.h" |
12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
13 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
14 #include "base/path_service.h" | 15 #include "base/path_service.h" |
| 16 #include "base/scoped_native_library.h" |
15 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "chrome/common/chrome_paths.h" |
16 #include "chrome/common/chrome_utility_messages.h" | 19 #include "chrome/common/chrome_utility_messages.h" |
17 #include "chrome/common/extensions/chrome_extensions_client.h" | 20 #include "chrome/common/extensions/chrome_extensions_client.h" |
18 #include "chrome/common/extensions/extension_l10n_util.h" | 21 #include "chrome/common/extensions/extension_l10n_util.h" |
19 #include "chrome/common/extensions/update_manifest.h" | 22 #include "chrome/common/extensions/update_manifest.h" |
20 #include "chrome/common/safe_browsing/zip_analyzer.h" | 23 #include "chrome/common/safe_browsing/zip_analyzer.h" |
21 #include "chrome/utility/extensions/unpacker.h" | 24 #include "chrome/utility/extensions/unpacker.h" |
22 #include "chrome/utility/profile_import_handler.h" | 25 #include "chrome/utility/profile_import_handler.h" |
23 #include "chrome/utility/web_resource_unpacker.h" | 26 #include "chrome/utility/web_resource_unpacker.h" |
24 #include "content/public/child/image_decoder_utils.h" | 27 #include "content/public/child/image_decoder_utils.h" |
25 #include "content/public/common/content_paths.h" | 28 #include "content/public/common/content_paths.h" |
26 #include "content/public/utility/utility_thread.h" | 29 #include "content/public/utility/utility_thread.h" |
27 #include "extensions/common/extension.h" | 30 #include "extensions/common/extension.h" |
28 #include "extensions/common/manifest.h" | 31 #include "extensions/common/manifest.h" |
29 #include "media/base/media.h" | 32 #include "media/base/media.h" |
30 #include "media/base/media_file_checker.h" | 33 #include "media/base/media_file_checker.h" |
31 #include "printing/page_range.h" | 34 #include "printing/page_range.h" |
| 35 #include "printing/pdf_render_settings.h" |
32 #include "third_party/skia/include/core/SkBitmap.h" | 36 #include "third_party/skia/include/core/SkBitmap.h" |
33 #include "third_party/zlib/google/zip.h" | 37 #include "third_party/zlib/google/zip.h" |
34 #include "ui/base/ui_base_switches.h" | 38 #include "ui/base/ui_base_switches.h" |
35 #include "ui/gfx/codec/jpeg_codec.h" | 39 #include "ui/gfx/codec/jpeg_codec.h" |
36 #include "ui/gfx/rect.h" | 40 #include "ui/gfx/rect.h" |
37 #include "ui/gfx/size.h" | 41 #include "ui/gfx/size.h" |
38 | 42 |
39 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
40 #include "base/file_util.h" | |
41 #include "base/path_service.h" | |
42 #include "base/win/iat_patch_function.h" | 44 #include "base/win/iat_patch_function.h" |
43 #include "base/win/scoped_handle.h" | 45 #include "base/win/scoped_handle.h" |
44 #include "chrome/common/chrome_paths.h" | |
45 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h" | 46 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h" |
46 #include "printing/emf_win.h" | 47 #include "printing/emf_win.h" |
47 #include "ui/gfx/gdi_util.h" | 48 #include "ui/gfx/gdi_util.h" |
48 #endif // defined(OS_WIN) | 49 #endif // defined(OS_WIN) |
49 | 50 |
50 #if defined(OS_MACOSX) | 51 #if defined(OS_MACOSX) |
51 #include "chrome/utility/media_galleries/iphoto_library_parser.h" | 52 #include "chrome/utility/media_galleries/iphoto_library_parser.h" |
52 #endif // defined(OS_MACOSX) | 53 #endif // defined(OS_MACOSX) |
53 | 54 |
54 #if defined(OS_WIN) || defined(OS_MACOSX) | 55 #if defined(OS_WIN) || defined(OS_MACOSX) |
(...skipping 18 matching lines...) Expand all Loading... |
73 namespace { | 74 namespace { |
74 | 75 |
75 bool Send(IPC::Message* message) { | 76 bool Send(IPC::Message* message) { |
76 return content::UtilityThread::Get()->Send(message); | 77 return content::UtilityThread::Get()->Send(message); |
77 } | 78 } |
78 | 79 |
79 void ReleaseProcessIfNeeded() { | 80 void ReleaseProcessIfNeeded() { |
80 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); | 81 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
81 } | 82 } |
82 | 83 |
| 84 class PdfFunctionsBase { |
| 85 public: |
| 86 PdfFunctionsBase() : render_pdf_to_bitmap_func_(NULL), |
| 87 get_pdf_doc_info_func_(NULL) {} |
| 88 |
| 89 bool Init() { |
| 90 base::FilePath pdf_module_path; |
| 91 if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path) || |
| 92 !base::PathExists(pdf_module_path)) { |
| 93 return false; |
| 94 } |
| 95 |
| 96 pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); |
| 97 if (!pdf_lib_.is_valid()) { |
| 98 LOG(WARNING) << "Couldn't load PDF plugin"; |
| 99 return false; |
| 100 } |
| 101 |
| 102 render_pdf_to_bitmap_func_ = |
| 103 reinterpret_cast<RenderPDFPageToBitmapProc>( |
| 104 pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap")); |
| 105 LOG_IF(WARNING, !render_pdf_to_bitmap_func_) << |
| 106 "Missing RenderPDFPageToBitmap"; |
| 107 |
| 108 get_pdf_doc_info_func_ = |
| 109 reinterpret_cast<GetPDFDocInfoProc>( |
| 110 pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); |
| 111 LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; |
| 112 |
| 113 if (!render_pdf_to_bitmap_func_ || !get_pdf_doc_info_func_ || |
| 114 !PlatformInit(pdf_module_path, pdf_lib_)) { |
| 115 Reset(); |
| 116 } |
| 117 |
| 118 return IsValid(); |
| 119 } |
| 120 |
| 121 bool IsValid() const { |
| 122 return pdf_lib_.is_valid(); |
| 123 } |
| 124 |
| 125 void Reset() { |
| 126 pdf_lib_.Reset(NULL); |
| 127 } |
| 128 |
| 129 bool RenderPDFPageToBitmap(const void* pdf_buffer, |
| 130 int pdf_buffer_size, |
| 131 int page_number, |
| 132 void* bitmap_buffer, |
| 133 int bitmap_width, |
| 134 int bitmap_height, |
| 135 int dpi_x, |
| 136 int dpi_y, |
| 137 bool autorotate) { |
| 138 if (!render_pdf_to_bitmap_func_) |
| 139 return false; |
| 140 return render_pdf_to_bitmap_func_(pdf_buffer, pdf_buffer_size, page_number, |
| 141 bitmap_buffer, bitmap_width, |
| 142 bitmap_height, dpi_x, dpi_y, autorotate); |
| 143 } |
| 144 |
| 145 bool GetPDFDocInfo(const void* pdf_buffer, |
| 146 int buffer_size, |
| 147 int* page_count, |
| 148 double* max_page_width) { |
| 149 if (!get_pdf_doc_info_func_) |
| 150 return false; |
| 151 return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, |
| 152 max_page_width); |
| 153 } |
| 154 |
| 155 protected: |
| 156 virtual bool PlatformInit( |
| 157 const base::FilePath& pdf_module_path, |
| 158 const base::ScopedNativeLibrary& pdf_lib) { |
| 159 return true; |
| 160 }; |
| 161 |
| 162 private: |
| 163 // Exported by PDF plugin. |
| 164 typedef bool (*RenderPDFPageToBitmapProc)(const void* pdf_buffer, |
| 165 int pdf_buffer_size, |
| 166 int page_number, |
| 167 void* bitmap_buffer, |
| 168 int bitmap_width, |
| 169 int bitmap_height, |
| 170 int dpi_x, |
| 171 int dpi_y, |
| 172 bool autorotate); |
| 173 typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, |
| 174 int buffer_size, int* page_count, |
| 175 double* max_page_width); |
| 176 |
| 177 RenderPDFPageToBitmapProc render_pdf_to_bitmap_func_; |
| 178 GetPDFDocInfoProc get_pdf_doc_info_func_; |
| 179 |
| 180 base::ScopedNativeLibrary pdf_lib_; |
| 181 DISALLOW_COPY_AND_ASSIGN(PdfFunctionsBase); |
| 182 }; |
| 183 |
| 184 #if defined(OS_WIN) |
| 185 // The 2 below IAT patch functions are almost identical to the code in |
| 186 // render_process_impl.cc. This is needed to work around specific Windows APIs |
| 187 // used by the Chrome PDF plugin that will fail in the sandbox. |
| 188 static base::win::IATPatchFunction g_iat_patch_createdca; |
| 189 HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, |
| 190 LPCSTR device_name, |
| 191 LPCSTR output, |
| 192 const DEVMODEA* init_data) { |
| 193 if (driver_name && (std::string("DISPLAY") == driver_name)) { |
| 194 // CreateDC fails behind the sandbox, but not CreateCompatibleDC. |
| 195 return CreateCompatibleDC(NULL); |
| 196 } |
| 197 |
| 198 NOTREACHED(); |
| 199 return CreateDCA(driver_name, device_name, output, init_data); |
| 200 } |
| 201 |
| 202 static base::win::IATPatchFunction g_iat_patch_get_font_data; |
| 203 DWORD WINAPI UtilityProcess_GetFontDataPatch( |
| 204 HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { |
| 205 int rv = GetFontData(hdc, table, offset, buffer, length); |
| 206 if (rv == GDI_ERROR && hdc) { |
| 207 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); |
| 208 |
| 209 LOGFONT logfont; |
| 210 if (GetObject(font, sizeof(LOGFONT), &logfont)) { |
| 211 content::UtilityThread::Get()->PreCacheFont(logfont); |
| 212 rv = GetFontData(hdc, table, offset, buffer, length); |
| 213 content::UtilityThread::Get()->ReleaseCachedFonts(); |
| 214 } |
| 215 } |
| 216 return rv; |
| 217 } |
| 218 |
| 219 class PdfFunctionsWin : public PdfFunctionsBase { |
| 220 public: |
| 221 PdfFunctionsWin() : render_pdf_to_dc_func_(NULL) { |
| 222 } |
| 223 |
| 224 bool PlatformInit( |
| 225 const base::FilePath& pdf_module_path, |
| 226 const base::ScopedNativeLibrary& pdf_lib) OVERRIDE { |
| 227 // Patch the IAT for handling specific APIs known to fail in the sandbox. |
| 228 if (!g_iat_patch_createdca.is_patched()) { |
| 229 g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), |
| 230 "gdi32.dll", "CreateDCA", |
| 231 UtilityProcess_CreateDCAPatch); |
| 232 } |
| 233 |
| 234 if (!g_iat_patch_get_font_data.is_patched()) { |
| 235 g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), |
| 236 "gdi32.dll", "GetFontData", |
| 237 UtilityProcess_GetFontDataPatch); |
| 238 } |
| 239 render_pdf_to_dc_func_ = |
| 240 reinterpret_cast<RenderPDFPageToDCProc>( |
| 241 pdf_lib.GetFunctionPointer("RenderPDFPageToDC")); |
| 242 LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; |
| 243 |
| 244 return render_pdf_to_dc_func_ != NULL; |
| 245 } |
| 246 |
| 247 bool RenderPDFPageToDC(const void* pdf_buffer, |
| 248 int buffer_size, |
| 249 int page_number, |
| 250 HDC dc, |
| 251 int dpi_x, |
| 252 int dpi_y, |
| 253 int bounds_origin_x, |
| 254 int bounds_origin_y, |
| 255 int bounds_width, |
| 256 int bounds_height, |
| 257 bool fit_to_bounds, |
| 258 bool stretch_to_bounds, |
| 259 bool keep_aspect_ratio, |
| 260 bool center_in_bounds, |
| 261 bool autorotate) { |
| 262 if (!render_pdf_to_dc_func_) |
| 263 return false; |
| 264 return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, |
| 265 dc, dpi_x, dpi_y, bounds_origin_x, |
| 266 bounds_origin_y, bounds_width, bounds_height, |
| 267 fit_to_bounds, stretch_to_bounds, |
| 268 keep_aspect_ratio, center_in_bounds, |
| 269 autorotate); |
| 270 } |
| 271 |
| 272 private: |
| 273 // Exported by PDF plugin. |
| 274 typedef bool (*RenderPDFPageToDCProc)( |
| 275 const void* pdf_buffer, int buffer_size, int page_number, HDC dc, |
| 276 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, |
| 277 int bounds_width, int bounds_height, bool fit_to_bounds, |
| 278 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, |
| 279 bool autorotate); |
| 280 RenderPDFPageToDCProc render_pdf_to_dc_func_; |
| 281 |
| 282 DISALLOW_COPY_AND_ASSIGN(PdfFunctionsWin); |
| 283 }; |
| 284 |
| 285 typedef PdfFunctionsWin PdfFunctions; |
| 286 #else // OS_WIN |
| 287 typedef PdfFunctionsBase PdfFunctions; |
| 288 #endif // OS_WIN |
| 289 |
| 290 static base::LazyInstance<PdfFunctions> g_pdf_lib = LAZY_INSTANCE_INITIALIZER; |
| 291 |
83 } // namespace | 292 } // namespace |
84 | 293 |
85 ChromeContentUtilityClient::ChromeContentUtilityClient() { | 294 ChromeContentUtilityClient::ChromeContentUtilityClient() { |
86 #if !defined(OS_ANDROID) | 295 #if !defined(OS_ANDROID) |
87 handlers_.push_back(new ProfileImportHandler()); | 296 handlers_.push_back(new ProfileImportHandler()); |
88 #endif // OS_ANDROID | 297 #endif // OS_ANDROID |
89 | 298 |
90 #if defined(ENABLE_MDNS) | 299 #if defined(ENABLE_MDNS) |
91 if (CommandLine::ForCurrentProcess()->HasSwitch( | 300 if (CommandLine::ForCurrentProcess()->HasSwitch( |
92 switches::kUtilityProcessEnableMDns)) { | 301 switches::kUtilityProcessEnableMDns)) { |
93 handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler()); | 302 handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler()); |
94 } | 303 } |
95 #endif // ENABLE_MDNS | 304 #endif // ENABLE_MDNS |
96 } | 305 } |
97 | 306 |
98 ChromeContentUtilityClient::~ChromeContentUtilityClient() { | 307 ChromeContentUtilityClient::~ChromeContentUtilityClient() { |
99 } | 308 } |
100 | 309 |
101 void ChromeContentUtilityClient::UtilityThreadStarted() { | 310 void ChromeContentUtilityClient::UtilityThreadStarted() { |
102 #if defined(OS_WIN) | |
103 // Load the pdf plugin before the sandbox is turned on. This is for Windows | |
104 // only because we need this DLL only on Windows. | |
105 base::FilePath pdf; | |
106 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) && | |
107 base::PathExists(pdf)) { | |
108 bool rv = !!LoadLibrary(pdf.value().c_str()); | |
109 DCHECK(rv) << "Couldn't load PDF plugin"; | |
110 } | |
111 #endif | |
112 | |
113 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 311 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
114 std::string lang = command_line->GetSwitchValueASCII(switches::kLang); | 312 std::string lang = command_line->GetSwitchValueASCII(switches::kLang); |
115 if (!lang.empty()) | 313 if (!lang.empty()) |
116 extension_l10n_util::SetProcessLocale(lang); | 314 extension_l10n_util::SetProcessLocale(lang); |
117 } | 315 } |
118 | 316 |
119 bool ChromeContentUtilityClient::OnMessageReceived( | 317 bool ChromeContentUtilityClient::OnMessageReceived( |
120 const IPC::Message& message) { | 318 const IPC::Message& message) { |
121 bool handled = true; | 319 bool handled = true; |
122 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) | 320 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 373 |
176 return handled; | 374 return handled; |
177 } | 375 } |
178 | 376 |
179 // static | 377 // static |
180 void ChromeContentUtilityClient::PreSandboxStartup() { | 378 void ChromeContentUtilityClient::PreSandboxStartup() { |
181 #if defined(ENABLE_MDNS) | 379 #if defined(ENABLE_MDNS) |
182 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup(); | 380 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup(); |
183 #endif // ENABLE_MDNS | 381 #endif // ENABLE_MDNS |
184 | 382 |
| 383 g_pdf_lib.Get().Init(); |
| 384 |
185 // Load media libraries for media file validation. | 385 // Load media libraries for media file validation. |
186 base::FilePath media_path; | 386 base::FilePath media_path; |
187 PathService::Get(content::DIR_MEDIA_LIBS, &media_path); | 387 PathService::Get(content::DIR_MEDIA_LIBS, &media_path); |
188 if (!media_path.empty()) | 388 if (!media_path.empty()) |
189 media::InitializeMediaLibrary(media_path); | 389 media::InitializeMediaLibrary(media_path); |
190 } | 390 } |
191 | 391 |
192 void ChromeContentUtilityClient::OnUnpackExtension( | 392 void ChromeContentUtilityClient::OnUnpackExtension( |
193 const base::FilePath& extension_path, | 393 const base::FilePath& extension_path, |
194 const std::string& extension_id, | 394 const std::string& extension_id, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); | 499 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); |
300 else | 500 else |
301 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); | 501 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); |
302 ReleaseProcessIfNeeded(); | 502 ReleaseProcessIfNeeded(); |
303 } | 503 } |
304 #endif // defined(OS_CHROMEOS) | 504 #endif // defined(OS_CHROMEOS) |
305 | 505 |
306 void ChromeContentUtilityClient::OnRenderPDFPagesToMetafile( | 506 void ChromeContentUtilityClient::OnRenderPDFPagesToMetafile( |
307 base::PlatformFile pdf_file, | 507 base::PlatformFile pdf_file, |
308 const base::FilePath& metafile_path, | 508 const base::FilePath& metafile_path, |
309 const printing::PdfRenderSettings& pdf_render_settings, | 509 const printing::PdfRenderSettings& settings, |
310 const std::vector<printing::PageRange>& page_ranges) { | 510 const std::vector<printing::PageRange>& page_ranges) { |
311 bool succeeded = false; | 511 bool succeeded = false; |
312 #if defined(OS_WIN) | 512 #if defined(OS_WIN) |
313 int highest_rendered_page_number = 0; | 513 int highest_rendered_page_number = 0; |
314 double scale_factor = 1.0; | 514 double scale_factor = 1.0; |
315 succeeded = RenderPDFToWinMetafile(pdf_file, | 515 succeeded = RenderPDFToWinMetafile(pdf_file, |
316 metafile_path, | 516 metafile_path, |
317 pdf_render_settings.area(), | 517 settings, |
318 pdf_render_settings.dpi(), | |
319 pdf_render_settings.autorotate(), | |
320 page_ranges, | 518 page_ranges, |
321 &highest_rendered_page_number, | 519 &highest_rendered_page_number, |
322 &scale_factor); | 520 &scale_factor); |
323 if (succeeded) { | 521 if (succeeded) { |
324 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Succeeded( | 522 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Succeeded( |
325 highest_rendered_page_number, scale_factor)); | 523 highest_rendered_page_number, scale_factor)); |
326 } | 524 } |
327 #endif // defined(OS_WIN) | 525 #endif // defined(OS_WIN) |
328 if (!succeeded) { | 526 if (!succeeded) { |
329 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); | 527 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); |
330 } | 528 } |
331 ReleaseProcessIfNeeded(); | 529 ReleaseProcessIfNeeded(); |
332 } | 530 } |
333 | 531 |
334 #if defined(OS_WIN) | 532 #if defined(OS_WIN) |
335 // Exported by pdf.dll | |
336 typedef bool (*RenderPDFPageToDCProc)( | |
337 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, | |
338 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, | |
339 int bounds_width, int bounds_height, bool fit_to_bounds, | |
340 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, | |
341 bool autorotate); | |
342 | |
343 typedef bool (*GetPDFDocInfoProc)(const unsigned char* pdf_buffer, | |
344 int buffer_size, int* page_count, | |
345 double* max_page_width); | |
346 | |
347 // The 2 below IAT patch functions are almost identical to the code in | |
348 // render_process_impl.cc. This is needed to work around specific Windows APIs | |
349 // used by the Chrome PDF plugin that will fail in the sandbox. | |
350 static base::win::IATPatchFunction g_iat_patch_createdca; | |
351 HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, | |
352 LPCSTR device_name, | |
353 LPCSTR output, | |
354 const DEVMODEA* init_data) { | |
355 if (driver_name && | |
356 (std::string("DISPLAY") == std::string(driver_name))) | |
357 // CreateDC fails behind the sandbox, but not CreateCompatibleDC. | |
358 return CreateCompatibleDC(NULL); | |
359 | |
360 NOTREACHED(); | |
361 return CreateDCA(driver_name, device_name, output, init_data); | |
362 } | |
363 | |
364 static base::win::IATPatchFunction g_iat_patch_get_font_data; | |
365 DWORD WINAPI UtilityProcess_GetFontDataPatch( | |
366 HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { | |
367 int rv = GetFontData(hdc, table, offset, buffer, length); | |
368 if (rv == GDI_ERROR && hdc) { | |
369 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); | |
370 | |
371 LOGFONT logfont; | |
372 if (GetObject(font, sizeof(LOGFONT), &logfont)) { | |
373 content::UtilityThread::Get()->PreCacheFont(logfont); | |
374 rv = GetFontData(hdc, table, offset, buffer, length); | |
375 content::UtilityThread::Get()->ReleaseCachedFonts(); | |
376 } | |
377 } | |
378 return rv; | |
379 } | |
380 | |
381 bool ChromeContentUtilityClient::RenderPDFToWinMetafile( | 533 bool ChromeContentUtilityClient::RenderPDFToWinMetafile( |
382 base::PlatformFile pdf_file, | 534 base::PlatformFile pdf_file, |
383 const base::FilePath& metafile_path, | 535 const base::FilePath& metafile_path, |
384 const gfx::Rect& render_area, | 536 const printing::PdfRenderSettings& settings, |
385 int render_dpi, | |
386 bool autorotate, | |
387 const std::vector<printing::PageRange>& page_ranges, | 537 const std::vector<printing::PageRange>& page_ranges, |
388 int* highest_rendered_page_number, | 538 int* highest_rendered_page_number, |
389 double* scale_factor) { | 539 double* scale_factor) { |
390 *highest_rendered_page_number = -1; | 540 *highest_rendered_page_number = -1; |
391 *scale_factor = 1.0; | 541 *scale_factor = 1.0; |
392 base::win::ScopedHandle file(pdf_file); | 542 base::win::ScopedHandle file(pdf_file); |
393 base::FilePath pdf_module_path; | 543 |
394 PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path); | 544 if (!g_pdf_lib.Get().IsValid()) |
395 HMODULE pdf_module = GetModuleHandle(pdf_module_path.value().c_str()); | |
396 if (!pdf_module) | |
397 return false; | 545 return false; |
398 | 546 |
399 RenderPDFPageToDCProc render_proc = | |
400 reinterpret_cast<RenderPDFPageToDCProc>( | |
401 GetProcAddress(pdf_module, "RenderPDFPageToDC")); | |
402 if (!render_proc) | |
403 return false; | |
404 | |
405 GetPDFDocInfoProc get_info_proc = reinterpret_cast<GetPDFDocInfoProc>( | |
406 GetProcAddress(pdf_module, "GetPDFDocInfo")); | |
407 if (!get_info_proc) | |
408 return false; | |
409 | |
410 // Patch the IAT for handling specific APIs known to fail in the sandbox. | |
411 if (!g_iat_patch_createdca.is_patched()) | |
412 g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), | |
413 "gdi32.dll", "CreateDCA", | |
414 UtilityProcess_CreateDCAPatch); | |
415 | |
416 if (!g_iat_patch_get_font_data.is_patched()) | |
417 g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), | |
418 "gdi32.dll", "GetFontData", | |
419 UtilityProcess_GetFontDataPatch); | |
420 | |
421 // TODO(sanjeevr): Add a method to the PDF DLL that takes in a file handle | 547 // TODO(sanjeevr): Add a method to the PDF DLL that takes in a file handle |
422 // and a page range array. That way we don't need to read the entire PDF into | 548 // and a page range array. That way we don't need to read the entire PDF into |
423 // memory. | 549 // memory. |
424 DWORD length = ::GetFileSize(file, NULL); | 550 DWORD length = ::GetFileSize(file, NULL); |
425 if (length == INVALID_FILE_SIZE) | 551 if (length == INVALID_FILE_SIZE) |
426 return false; | 552 return false; |
427 | 553 |
428 std::vector<uint8> buffer; | 554 std::vector<uint8> buffer; |
429 buffer.resize(length); | 555 buffer.resize(length); |
430 DWORD bytes_read = 0; | 556 DWORD bytes_read = 0; |
431 if (!ReadFile(pdf_file, &buffer.front(), length, &bytes_read, NULL) || | 557 if (!ReadFile(pdf_file, &buffer.front(), length, &bytes_read, NULL) || |
432 (bytes_read != length)) | 558 (bytes_read != length)) { |
433 return false; | 559 return false; |
| 560 } |
434 | 561 |
435 int total_page_count = 0; | 562 int total_page_count = 0; |
436 if (!get_info_proc(&buffer.front(), buffer.size(), &total_page_count, NULL)) | 563 if (!g_pdf_lib.Get().GetPDFDocInfo(&buffer.front(), buffer.size(), |
| 564 &total_page_count, NULL)) { |
437 return false; | 565 return false; |
| 566 } |
438 | 567 |
439 printing::Emf metafile; | 568 printing::Emf metafile; |
440 metafile.InitToFile(metafile_path); | 569 metafile.InitToFile(metafile_path); |
441 // We need to scale down DC to fit an entire page into DC available area. | 570 // We need to scale down DC to fit an entire page into DC available area. |
442 // Current metafile is based on screen DC and have current screen size. | 571 // Current metafile is based on screen DC and have current screen size. |
443 // Writing outside of those boundaries will result in the cut-off output. | 572 // Writing outside of those boundaries will result in the cut-off output. |
444 // On metafiles (this is the case here), scaling down will still record | 573 // On metafiles (this is the case here), scaling down will still record |
445 // original coordinates and we'll be able to print in full resolution. | 574 // original coordinates and we'll be able to print in full resolution. |
446 // Before playback we'll need to counter the scaling up that will happen | 575 // Before playback we'll need to counter the scaling up that will happen |
447 // in the service (print_system_win.cc). | 576 // in the service (print_system_win.cc). |
448 *scale_factor = gfx::CalculatePageScale(metafile.context(), | 577 *scale_factor = gfx::CalculatePageScale(metafile.context(), |
449 render_area.right(), | 578 settings.area().right(), |
450 render_area.bottom()); | 579 settings.area().bottom()); |
451 gfx::ScaleDC(metafile.context(), *scale_factor); | 580 gfx::ScaleDC(metafile.context(), *scale_factor); |
452 | 581 |
453 bool ret = false; | 582 bool ret = false; |
454 std::vector<printing::PageRange>::const_iterator iter; | 583 std::vector<printing::PageRange>::const_iterator iter; |
455 for (iter = page_ranges.begin(); iter != page_ranges.end(); ++iter) { | 584 for (iter = page_ranges.begin(); iter != page_ranges.end(); ++iter) { |
456 for (int page_number = iter->from; page_number <= iter->to; ++page_number) { | 585 for (int page_number = iter->from; page_number <= iter->to; ++page_number) { |
457 if (page_number >= total_page_count) | 586 if (page_number >= total_page_count) |
458 break; | 587 break; |
459 // The underlying metafile is of type Emf and ignores the arguments passed | 588 // The underlying metafile is of type Emf and ignores the arguments passed |
460 // to StartPage. | 589 // to StartPage. |
461 metafile.StartPage(gfx::Size(), gfx::Rect(), 1); | 590 metafile.StartPage(gfx::Size(), gfx::Rect(), 1); |
462 if (render_proc(&buffer.front(), buffer.size(), page_number, | 591 if (g_pdf_lib.Get().RenderPDFPageToDC( |
463 metafile.context(), render_dpi, render_dpi, | 592 &buffer.front(), buffer.size(), page_number, metafile.context(), |
464 render_area.x(), render_area.y(), render_area.width(), | 593 settings.dpi(), settings.dpi(), settings.area().x(), |
465 render_area.height(), true, false, true, true, | 594 settings.area().y(), settings.area().width(), |
466 autorotate)) | 595 settings.area().height(), true, false, true, true, |
| 596 settings.autorotate())) { |
467 if (*highest_rendered_page_number < page_number) | 597 if (*highest_rendered_page_number < page_number) |
468 *highest_rendered_page_number = page_number; | 598 *highest_rendered_page_number = page_number; |
469 ret = true; | 599 ret = true; |
| 600 } |
470 metafile.FinishPage(); | 601 metafile.FinishPage(); |
471 } | 602 } |
472 } | 603 } |
473 metafile.FinishDocument(); | 604 metafile.FinishDocument(); |
474 return ret; | 605 return ret; |
475 } | 606 } |
476 #endif // defined(OS_WIN) | 607 #endif // defined(OS_WIN) |
477 | 608 |
478 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( | 609 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( |
479 const std::vector<unsigned char>& encoded_data) { | 610 const std::vector<unsigned char>& encoded_data) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 picasa::PicasaAlbumsIndexer indexer(album_uids); | 754 picasa::PicasaAlbumsIndexer indexer(album_uids); |
624 indexer.ParseFolderINI(folders_inis); | 755 indexer.ParseFolderINI(folders_inis); |
625 | 756 |
626 Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished( | 757 Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished( |
627 indexer.albums_images())); | 758 indexer.albums_images())); |
628 ReleaseProcessIfNeeded(); | 759 ReleaseProcessIfNeeded(); |
629 } | 760 } |
630 #endif // defined(OS_WIN) || defined(OS_MACOSX) | 761 #endif // defined(OS_WIN) || defined(OS_MACOSX) |
631 | 762 |
632 } // namespace chrome | 763 } // namespace chrome |
OLD | NEW |