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.h" | 21 #include "chrome/common/extensions/extension.h" |
19 #include "chrome/common/extensions/extension_l10n_util.h" | 22 #include "chrome/common/extensions/extension_l10n_util.h" |
20 #include "chrome/common/extensions/update_manifest.h" | 23 #include "chrome/common/extensions/update_manifest.h" |
21 #include "chrome/common/safe_browsing/zip_analyzer.h" | 24 #include "chrome/common/safe_browsing/zip_analyzer.h" |
22 #include "chrome/utility/extensions/unpacker.h" | 25 #include "chrome/utility/extensions/unpacker.h" |
23 #include "chrome/utility/profile_import_handler.h" | 26 #include "chrome/utility/profile_import_handler.h" |
24 #include "chrome/utility/web_resource_unpacker.h" | 27 #include "chrome/utility/web_resource_unpacker.h" |
25 #include "content/public/child/image_decoder_utils.h" | 28 #include "content/public/child/image_decoder_utils.h" |
26 #include "content/public/common/content_paths.h" | 29 #include "content/public/common/content_paths.h" |
27 #include "content/public/utility/utility_thread.h" | 30 #include "content/public/utility/utility_thread.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" |
32 #include "third_party/skia/include/core/SkBitmap.h" | 35 #include "third_party/skia/include/core/SkBitmap.h" |
33 #include "third_party/zlib/google/zip.h" | 36 #include "third_party/zlib/google/zip.h" |
34 #include "ui/base/ui_base_switches.h" | 37 #include "ui/base/ui_base_switches.h" |
35 #include "ui/gfx/codec/jpeg_codec.h" | 38 #include "ui/gfx/codec/jpeg_codec.h" |
36 #include "ui/gfx/rect.h" | 39 #include "ui/gfx/rect.h" |
37 #include "ui/gfx/size.h" | 40 #include "ui/gfx/size.h" |
38 | 41 |
39 #if defined(OS_WIN) | 42 #if defined(OS_WIN) |
40 #include "base/file_util.h" | |
41 #include "base/path_service.h" | |
42 #include "base/win/iat_patch_function.h" | 43 #include "base/win/iat_patch_function.h" |
43 #include "base/win/scoped_handle.h" | 44 #include "base/win/scoped_handle.h" |
44 #include "chrome/common/chrome_paths.h" | |
45 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h" | 45 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h" |
46 #include "printing/emf_win.h" | 46 #include "printing/emf_win.h" |
47 #include "ui/gfx/gdi_util.h" | 47 #include "ui/gfx/gdi_util.h" |
48 #endif // defined(OS_WIN) | 48 #endif // defined(OS_WIN) |
49 | 49 |
50 #if defined(OS_MACOSX) | 50 #if defined(OS_MACOSX) |
51 #include "chrome/utility/media_galleries/iphoto_library_parser.h" | 51 #include "chrome/utility/media_galleries/iphoto_library_parser.h" |
52 #endif // defined(OS_MACOSX) | 52 #endif // defined(OS_MACOSX) |
53 | 53 |
54 #if defined(OS_WIN) || defined(OS_MACOSX) | 54 #if defined(OS_WIN) || defined(OS_MACOSX) |
(...skipping 18 matching lines...) Expand all Loading... |
73 namespace { | 73 namespace { |
74 | 74 |
75 bool Send(IPC::Message* message) { | 75 bool Send(IPC::Message* message) { |
76 return content::UtilityThread::Get()->Send(message); | 76 return content::UtilityThread::Get()->Send(message); |
77 } | 77 } |
78 | 78 |
79 void ReleaseProcessIfNeeded() { | 79 void ReleaseProcessIfNeeded() { |
80 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); | 80 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
81 } | 81 } |
82 | 82 |
| 83 class PdfFunctionsBase { |
| 84 public: |
| 85 PdfFunctionsBase() : render_pdf_to_bitmap_func_(NULL) {} |
| 86 |
| 87 bool Init() { |
| 88 base::FilePath pdf_module_path; |
| 89 if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path) || |
| 90 !base::PathExists(pdf_module_path)) { |
| 91 return false; |
| 92 } |
| 93 |
| 94 pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); |
| 95 if (!pdf_lib_.is_valid()) { |
| 96 LOG(WARNING) << "Couldn't load PDF plugin"; |
| 97 return false; |
| 98 } |
| 99 |
| 100 render_pdf_to_bitmap_func_ = |
| 101 reinterpret_cast<RenderPDFPageToBitmapProc>( |
| 102 pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap")); |
| 103 LOG_IF(WARNING, !render_pdf_to_bitmap_func_) << |
| 104 "Missing RenderPDFPageToBitmap"; |
| 105 |
| 106 if (!render_pdf_to_bitmap_func_ || !PlatformInit(pdf_module_path, pdf_lib_)) |
| 107 Reset(); |
| 108 |
| 109 return IsValid(); |
| 110 } |
| 111 |
| 112 bool IsValid() const { |
| 113 return pdf_lib_.is_valid(); |
| 114 } |
| 115 |
| 116 void Reset() { |
| 117 pdf_lib_.Reset(NULL); |
| 118 } |
| 119 |
| 120 bool RenderPDFPageToBitmap(const unsigned char* pdf_buffer, |
| 121 int buffer_size, |
| 122 int page_number, |
| 123 unsigned char* bitmap_buffer, |
| 124 int bitmap_height, |
| 125 int bitmap_width, |
| 126 int dpi_x, |
| 127 int dpi_y, |
| 128 bool autorotate) { |
| 129 if (!render_pdf_to_bitmap_func_) |
| 130 return false; |
| 131 return render_pdf_to_bitmap_func_(pdf_buffer, buffer_size, page_number, |
| 132 bitmap_buffer, bitmap_height, |
| 133 bitmap_width, dpi_x, dpi_y, autorotate); |
| 134 } |
| 135 |
| 136 protected: |
| 137 virtual bool PlatformInit( |
| 138 const base::FilePath& pdf_module_path, |
| 139 const base::ScopedNativeLibrary& pdf_lib) { |
| 140 return true; |
| 141 }; |
| 142 |
| 143 private: |
| 144 // Exported by PDF plugin. |
| 145 typedef bool (*RenderPDFPageToBitmapProc)(const unsigned char* pdf_buffer, |
| 146 int buffer_size, |
| 147 int page_number, |
| 148 unsigned char* bitmap_buffer, |
| 149 int bitmap_height, |
| 150 int bitmap_width, |
| 151 int dpi_x, |
| 152 int dpi_y, |
| 153 bool autorotate); |
| 154 RenderPDFPageToBitmapProc render_pdf_to_bitmap_func_; |
| 155 |
| 156 base::ScopedNativeLibrary pdf_lib_; |
| 157 DISALLOW_COPY_AND_ASSIGN(PdfFunctionsBase); |
| 158 }; |
| 159 |
| 160 #if defined(OS_WIN) |
| 161 // The 2 below IAT patch functions are almost identical to the code in |
| 162 // render_process_impl.cc. This is needed to work around specific Windows APIs |
| 163 // used by the Chrome PDF plugin that will fail in the sandbox. |
| 164 static base::win::IATPatchFunction g_iat_patch_createdca; |
| 165 HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, |
| 166 LPCSTR device_name, |
| 167 LPCSTR output, |
| 168 const DEVMODEA* init_data) { |
| 169 if (driver_name && (std::string("DISPLAY") == driver_name)) { |
| 170 // CreateDC fails behind the sandbox, but not CreateCompatibleDC. |
| 171 return CreateCompatibleDC(NULL); |
| 172 } |
| 173 |
| 174 NOTREACHED(); |
| 175 return CreateDCA(driver_name, device_name, output, init_data); |
| 176 } |
| 177 |
| 178 static base::win::IATPatchFunction g_iat_patch_get_font_data; |
| 179 DWORD WINAPI UtilityProcess_GetFontDataPatch( |
| 180 HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { |
| 181 int rv = GetFontData(hdc, table, offset, buffer, length); |
| 182 if (rv == GDI_ERROR && hdc) { |
| 183 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); |
| 184 |
| 185 LOGFONT logfont; |
| 186 if (GetObject(font, sizeof(LOGFONT), &logfont)) { |
| 187 content::UtilityThread::Get()->PreCacheFont(logfont); |
| 188 rv = GetFontData(hdc, table, offset, buffer, length); |
| 189 content::UtilityThread::Get()->ReleaseCachedFonts(); |
| 190 } |
| 191 } |
| 192 return rv; |
| 193 } |
| 194 |
| 195 class PdfFunctionsWin : public PdfFunctionsBase { |
| 196 public: |
| 197 PdfFunctionsWin() : render_pdf_to_dc_func_(NULL), |
| 198 get_pdf_doc_info_func_(NULL) { |
| 199 } |
| 200 |
| 201 bool PlatformInit( |
| 202 const base::FilePath& pdf_module_path, |
| 203 const base::ScopedNativeLibrary& pdf_lib) OVERRIDE { |
| 204 // Patch the IAT for handling specific APIs known to fail in the sandbox. |
| 205 if (!g_iat_patch_createdca.is_patched()) { |
| 206 g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), |
| 207 "gdi32.dll", "CreateDCA", |
| 208 UtilityProcess_CreateDCAPatch); |
| 209 } |
| 210 |
| 211 if (!g_iat_patch_get_font_data.is_patched()) { |
| 212 g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), |
| 213 "gdi32.dll", "GetFontData", |
| 214 UtilityProcess_GetFontDataPatch); |
| 215 } |
| 216 render_pdf_to_dc_func_ = |
| 217 reinterpret_cast<RenderPDFPageToDCProc>( |
| 218 pdf_lib.GetFunctionPointer("RenderPDFPageToDC")); |
| 219 LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; |
| 220 |
| 221 get_pdf_doc_info_func_ = |
| 222 reinterpret_cast<GetPDFDocInfoProc>( |
| 223 pdf_lib.GetFunctionPointer("GetPDFDocInfo")); |
| 224 LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; |
| 225 return render_pdf_to_dc_func_ && get_pdf_doc_info_func_; |
| 226 } |
| 227 |
| 228 bool RenderPDFPageToDC(const unsigned char* pdf_buffer, |
| 229 int buffer_size, |
| 230 int page_number, |
| 231 HDC dc, |
| 232 int dpi_x, |
| 233 int dpi_y, |
| 234 int bounds_origin_x, |
| 235 int bounds_origin_y, |
| 236 int bounds_width, |
| 237 int bounds_height, |
| 238 bool fit_to_bounds, |
| 239 bool stretch_to_bounds, |
| 240 bool keep_aspect_ratio, |
| 241 bool center_in_bounds, |
| 242 bool autorotate) { |
| 243 if (!render_pdf_to_dc_func_) |
| 244 return false; |
| 245 return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, |
| 246 dc, dpi_x, dpi_y, bounds_origin_x, |
| 247 bounds_origin_y, bounds_width, bounds_height, |
| 248 fit_to_bounds, stretch_to_bounds, |
| 249 keep_aspect_ratio, center_in_bounds, |
| 250 autorotate); |
| 251 } |
| 252 |
| 253 bool GetPDFDocInfo(const unsigned char* pdf_buffer, |
| 254 int buffer_size, |
| 255 int* page_count, |
| 256 double* max_page_width) { |
| 257 if (!get_pdf_doc_info_func_) |
| 258 return false; |
| 259 return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, |
| 260 max_page_width); |
| 261 } |
| 262 |
| 263 private: |
| 264 // Exported by PDF plugin. |
| 265 typedef bool (*RenderPDFPageToDCProc)( |
| 266 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, |
| 267 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, |
| 268 int bounds_width, int bounds_height, bool fit_to_bounds, |
| 269 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, |
| 270 bool autorotate); |
| 271 typedef bool (*GetPDFDocInfoProc)(const unsigned char* pdf_buffer, |
| 272 int buffer_size, int* page_count, |
| 273 double* max_page_width); |
| 274 RenderPDFPageToDCProc render_pdf_to_dc_func_; |
| 275 GetPDFDocInfoProc get_pdf_doc_info_func_; |
| 276 |
| 277 DISALLOW_COPY_AND_ASSIGN(PdfFunctionsWin); |
| 278 }; |
| 279 |
| 280 typedef PdfFunctionsWin PdfFunctions; |
| 281 #else // OS_WIN |
| 282 typedef PdfFunctionsBase PdfFunctions; |
| 283 #endif // OS_WIN |
| 284 |
| 285 static base::LazyInstance<PdfFunctions> g_pdf_lib = LAZY_INSTANCE_INITIALIZER; |
| 286 |
83 } // namespace | 287 } // namespace |
84 | 288 |
85 ChromeContentUtilityClient::ChromeContentUtilityClient() { | 289 ChromeContentUtilityClient::ChromeContentUtilityClient() { |
86 #if !defined(OS_ANDROID) | 290 #if !defined(OS_ANDROID) |
87 handlers_.push_back(new ProfileImportHandler()); | 291 handlers_.push_back(new ProfileImportHandler()); |
88 #endif // OS_ANDROID | 292 #endif // OS_ANDROID |
89 | 293 |
90 #if defined(ENABLE_MDNS) | 294 #if defined(ENABLE_MDNS) |
91 if (CommandLine::ForCurrentProcess()->HasSwitch( | 295 if (CommandLine::ForCurrentProcess()->HasSwitch( |
92 switches::kUtilityProcessEnableMDns)) { | 296 switches::kUtilityProcessEnableMDns)) { |
93 handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler()); | 297 handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler()); |
94 } | 298 } |
95 #endif // ENABLE_MDNS | 299 #endif // ENABLE_MDNS |
96 } | 300 } |
97 | 301 |
98 ChromeContentUtilityClient::~ChromeContentUtilityClient() { | 302 ChromeContentUtilityClient::~ChromeContentUtilityClient() { |
99 } | 303 } |
100 | 304 |
101 void ChromeContentUtilityClient::UtilityThreadStarted() { | 305 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(); | 306 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
114 std::string lang = command_line->GetSwitchValueASCII(switches::kLang); | 307 std::string lang = command_line->GetSwitchValueASCII(switches::kLang); |
115 if (!lang.empty()) | 308 if (!lang.empty()) |
116 extension_l10n_util::SetProcessLocale(lang); | 309 extension_l10n_util::SetProcessLocale(lang); |
117 } | 310 } |
118 | 311 |
119 bool ChromeContentUtilityClient::OnMessageReceived( | 312 bool ChromeContentUtilityClient::OnMessageReceived( |
120 const IPC::Message& message) { | 313 const IPC::Message& message) { |
121 bool handled = true; | 314 bool handled = true; |
122 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) | 315 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 368 |
176 return handled; | 369 return handled; |
177 } | 370 } |
178 | 371 |
179 // static | 372 // static |
180 void ChromeContentUtilityClient::PreSandboxStartup() { | 373 void ChromeContentUtilityClient::PreSandboxStartup() { |
181 #if defined(ENABLE_MDNS) | 374 #if defined(ENABLE_MDNS) |
182 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup(); | 375 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup(); |
183 #endif // ENABLE_MDNS | 376 #endif // ENABLE_MDNS |
184 | 377 |
| 378 g_pdf_lib.Get().Init(); |
| 379 |
185 // Load media libraries for media file validation. | 380 // Load media libraries for media file validation. |
186 base::FilePath media_path; | 381 base::FilePath media_path; |
187 PathService::Get(content::DIR_MEDIA_LIBS, &media_path); | 382 PathService::Get(content::DIR_MEDIA_LIBS, &media_path); |
188 if (!media_path.empty()) | 383 if (!media_path.empty()) |
189 media::InitializeMediaLibrary(media_path); | 384 media::InitializeMediaLibrary(media_path); |
190 } | 385 } |
191 | 386 |
192 void ChromeContentUtilityClient::OnUnpackExtension( | 387 void ChromeContentUtilityClient::OnUnpackExtension( |
193 const base::FilePath& extension_path, | 388 const base::FilePath& extension_path, |
194 const std::string& extension_id, | 389 const std::string& extension_id, |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 highest_rendered_page_number, scale_factor)); | 520 highest_rendered_page_number, scale_factor)); |
326 } | 521 } |
327 #endif // defined(OS_WIN) | 522 #endif // defined(OS_WIN) |
328 if (!succeeded) { | 523 if (!succeeded) { |
329 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); | 524 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); |
330 } | 525 } |
331 ReleaseProcessIfNeeded(); | 526 ReleaseProcessIfNeeded(); |
332 } | 527 } |
333 | 528 |
334 #if defined(OS_WIN) | 529 #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 | 530 |
381 bool ChromeContentUtilityClient::RenderPDFToWinMetafile( | 531 bool ChromeContentUtilityClient::RenderPDFToWinMetafile( |
382 base::PlatformFile pdf_file, | 532 base::PlatformFile pdf_file, |
383 const base::FilePath& metafile_path, | 533 const base::FilePath& metafile_path, |
384 const gfx::Rect& render_area, | 534 const gfx::Rect& render_area, |
385 int render_dpi, | 535 int render_dpi, |
386 bool autorotate, | 536 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 render_area.right(), |
450 render_area.bottom()); | 579 render_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 render_dpi, render_dpi, render_area.x(), render_area.y(), |
465 render_area.height(), true, false, true, true, | 594 render_area.width(), render_area.height(), true, false, true, |
466 autorotate)) | 595 true, autorotate)) { |
467 if (*highest_rendered_page_number < page_number) | 596 if (*highest_rendered_page_number < page_number) |
468 *highest_rendered_page_number = page_number; | 597 *highest_rendered_page_number = page_number; |
469 ret = true; | 598 ret = true; |
| 599 } |
470 metafile.FinishPage(); | 600 metafile.FinishPage(); |
471 } | 601 } |
472 } | 602 } |
473 metafile.FinishDocument(); | 603 metafile.FinishDocument(); |
474 return ret; | 604 return ret; |
475 } | 605 } |
476 #endif // defined(OS_WIN) | 606 #endif // defined(OS_WIN) |
477 | 607 |
478 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( | 608 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( |
479 const std::vector<unsigned char>& encoded_data) { | 609 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); | 753 picasa::PicasaAlbumsIndexer indexer(album_uids); |
624 indexer.ParseFolderINI(folders_inis); | 754 indexer.ParseFolderINI(folders_inis); |
625 | 755 |
626 Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished( | 756 Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished( |
627 indexer.albums_images())); | 757 indexer.albums_images())); |
628 ReleaseProcessIfNeeded(); | 758 ReleaseProcessIfNeeded(); |
629 } | 759 } |
630 #endif // defined(OS_WIN) || defined(OS_MACOSX) | 760 #endif // defined(OS_WIN) || defined(OS_MACOSX) |
631 | 761 |
632 } // namespace chrome | 762 } // namespace chrome |
OLD | NEW |