diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index e73cc06bc464..ff9d14cf593a 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -64,6 +64,12 @@ void AtomMainDelegate::PreSandboxStartup() { std::string process_type = command_line->GetSwitchValueASCII( switches::kProcessType); +#if defined(OS_WIN) + if (process_type == switches::kUtilityProcess) { + AtomContentUtilityClient::PreSandboxStartup(); + } +#endif + // Only append arguments for browser process. if (!process_type.empty()) return; diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index cc739227aad8..06d0c3b82cfd 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -71,4 +71,9 @@ void AtomContentUtilityClient::OnStartupPing() { // Don't release the process, we assume further messages are on the way. } +// static +void AtomContentUtilityClient::PreSandboxStartup() { + PrintingHandler::PreSandboxStartup(); +} + } // namespace atom diff --git a/atom/utility/atom_content_utility_client.h b/atom/utility/atom_content_utility_client.h index 2c245b62f61e..756193d6d44c 100644 --- a/atom/utility/atom_content_utility_client.h +++ b/atom/utility/atom_content_utility_client.h @@ -31,6 +31,7 @@ class AtomContentUtilityClient : public content::ContentUtilityClient { void UtilityThreadStarted() override; bool OnMessageReceived(const IPC::Message& message) override; + static void PreSandboxStartup(); static void set_max_ipc_message_size_for_test(int64_t max_message_size) { max_ipc_message_size_ = max_message_size; diff --git a/chromium_src/chrome/utility/printing_handler.cc b/chromium_src/chrome/utility/printing_handler.cc index db6d9533cf51..7821c174c950 100644 --- a/chromium_src/chrome/utility/printing_handler.cc +++ b/chromium_src/chrome/utility/printing_handler.cc @@ -10,7 +10,6 @@ #include "base/scoped_native_library.h" #include "chrome/common/print_messages.h" #include "content/public/utility/utility_thread.h" -#include "pdf/pdf.h" #include "printing/page_range.h" #include "printing/pdf_render_settings.h" @@ -30,12 +29,111 @@ void ReleaseProcessIfNeeded() { content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } +class PdfFunctions { + public: + PdfFunctions() : get_pdf_doc_info_func_(NULL), + render_pdf_to_dc_func_(NULL) {} + + bool Init() { + base::FilePath pdf_module_path(FILE_PATH_LITERAL("pdf.dll")); + pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); + if (!pdf_lib_.is_valid()) { + LOG(WARNING) << "Couldn't load PDF plugin"; + return false; + } + + get_pdf_doc_info_func_ = + reinterpret_cast( + pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); + LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; + + render_pdf_to_dc_func_ = + reinterpret_cast( + pdf_lib_.GetFunctionPointer("RenderPDFPageToDC")); + LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; + + if (!get_pdf_doc_info_func_ || !render_pdf_to_dc_func_) { + Reset(); + } + + return IsValid(); + } + + bool IsValid() const { + return pdf_lib_.is_valid(); + } + + void Reset() { + pdf_lib_.Reset(NULL); + } + + bool GetPDFDocInfo(const void* pdf_buffer, + int buffer_size, + int* page_count, + double* max_page_width) { + if (!get_pdf_doc_info_func_) + return false; + return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, + max_page_width); + } + + bool RenderPDFPageToDC(const void* pdf_buffer, + int buffer_size, + int page_number, + HDC dc, + int dpi, + int bounds_origin_x, + int bounds_origin_y, + int bounds_width, + int bounds_height, + bool fit_to_bounds, + bool stretch_to_bounds, + bool keep_aspect_ratio, + bool center_in_bounds, + bool autorotate) { + if (!render_pdf_to_dc_func_) + return false; + return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, + dc, dpi, bounds_origin_x, + bounds_origin_y, bounds_width, bounds_height, + fit_to_bounds, stretch_to_bounds, + keep_aspect_ratio, center_in_bounds, + autorotate); + } + + private: + // Exported by PDF plugin. + typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, + int buffer_size, int* page_count, + double* max_page_width); + typedef bool (*RenderPDFPageToDCProc)( + const void* pdf_buffer, int buffer_size, int page_number, HDC dc, + int dpi, int bounds_origin_x, int bounds_origin_y, + int bounds_width, int bounds_height, bool fit_to_bounds, + bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, + bool autorotate); + + RenderPDFPageToDCProc render_pdf_to_dc_func_; + GetPDFDocInfoProc get_pdf_doc_info_func_; + + base::ScopedNativeLibrary pdf_lib_; + + DISALLOW_COPY_AND_ASSIGN(PdfFunctions); +}; + +base::LazyInstance g_pdf_lib = LAZY_INSTANCE_INITIALIZER; + } // namespace PrintingHandler::PrintingHandler() {} PrintingHandler::~PrintingHandler() {} +// static +void PrintingHandler::PreSandboxStartup() { + g_pdf_lib.Get().Init(); +} + bool PrintingHandler::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message) @@ -80,6 +178,9 @@ void PrintingHandler::OnRenderPDFPagesToMetafileStop() { } int PrintingHandler::LoadPDF(base::File pdf_file) { + if (!g_pdf_lib.Get().IsValid()) + return 0; + int64 length64 = pdf_file.GetLength(); if (length64 <= 0 || length64 > std::numeric_limits::max()) return 0; @@ -90,7 +191,7 @@ int PrintingHandler::LoadPDF(base::File pdf_file) { return 0; int total_page_count = 0; - if (!chrome_pdf::GetPDFDocInfo( + if (!g_pdf_lib.Get().GetPDFDocInfo( &pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) { return 0; } @@ -119,7 +220,7 @@ bool PrintingHandler::RenderPdfPageToMetafile(int page_number, // The underlying metafile is of type Emf and ignores the arguments passed // to StartPage. metafile.StartPage(gfx::Size(), gfx::Rect(), 1); - if (!chrome_pdf::RenderPDFPageToDC( + if (!g_pdf_lib.Get().RenderPDFPageToDC( &pdf_data_.front(), pdf_data_.size(), page_number, diff --git a/chromium_src/chrome/utility/printing_handler.h b/chromium_src/chrome/utility/printing_handler.h index b1f09acb9cc9..ad96dd704ffe 100644 --- a/chromium_src/chrome/utility/printing_handler.h +++ b/chromium_src/chrome/utility/printing_handler.h @@ -30,6 +30,8 @@ class PrintingHandler : public UtilityMessageHandler { // IPC::Listener: bool OnMessageReceived(const IPC::Message& message) override; + static void PrintingHandler::PreSandboxStartup(); + private: // IPC message handlers. #if defined(OS_WIN)