| 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/service/cloud_print/print_system.h" | 5 #include "chrome/service/cloud_print/print_system.h" |
| 6 | 6 |
| 7 #include <objidl.h> | 7 #include <objidl.h> |
| 8 #include <winspool.h> | 8 #include <winspool.h> |
| 9 #include <xpsprint.h> | 9 #include <xpsprint.h> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "base/win/object_watcher.h" | 16 #include "base/win/object_watcher.h" |
| 17 #include "base/win/scoped_bstr.h" | 17 #include "base/win/scoped_bstr.h" |
| 18 #include "base/win/scoped_comptr.h" | 18 #include "base/win/scoped_comptr.h" |
| 19 #include "base/win/scoped_hdc.h" | 19 #include "base/win/scoped_hdc.h" |
| 20 #include "chrome/common/child_process_logging.h" |
| 20 #include "chrome/service/service_process.h" | 21 #include "chrome/service/service_process.h" |
| 21 #include "chrome/service/service_utility_process_host.h" | 22 #include "chrome/service/service_utility_process_host.h" |
| 22 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
| 23 #include "printing/backend/print_backend.h" | 24 #include "printing/backend/print_backend.h" |
| 24 #include "printing/backend/print_backend_consts.h" | 25 #include "printing/backend/print_backend_consts.h" |
| 25 #include "printing/backend/win_helper.h" | 26 #include "printing/backend/win_helper.h" |
| 26 #include "printing/emf_win.h" | 27 #include "printing/emf_win.h" |
| 27 #include "printing/page_range.h" | 28 #include "printing/page_range.h" |
| 28 #include "printing/pdf_render_settings.h" | 29 #include "printing/pdf_render_settings.h" |
| 29 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 class Delegate { | 156 class Delegate { |
| 156 public: | 157 public: |
| 157 virtual ~Delegate() {} | 158 virtual ~Delegate() {} |
| 158 virtual void OnPrinterAdded() = 0; | 159 virtual void OnPrinterAdded() = 0; |
| 159 virtual void OnPrinterDeleted() = 0; | 160 virtual void OnPrinterDeleted() = 0; |
| 160 virtual void OnPrinterChanged() = 0; | 161 virtual void OnPrinterChanged() = 0; |
| 161 virtual void OnJobChanged() = 0; | 162 virtual void OnJobChanged() = 0; |
| 162 }; | 163 }; |
| 163 | 164 |
| 164 bool Start(const std::string& printer_name, Delegate* delegate) { | 165 bool Start(const std::string& printer_name, Delegate* delegate) { |
| 166 scoped_refptr<printing::PrintBackend> print_backend( |
| 167 printing::PrintBackend::CreateInstance(NULL)); |
| 168 printer_info_ = print_backend->GetPrinterDriverInfo(printer_name); |
| 169 child_process_logging::ScopedPrinterInfoSetter prn_info(printer_info_); |
| 170 |
| 165 delegate_ = delegate; | 171 delegate_ = delegate; |
| 166 // An empty printer name means watch the current server, we need to pass | 172 // An empty printer name means watch the current server, we need to pass |
| 167 // NULL to OpenPrinter. | 173 // NULL to OpenPrinter. |
| 168 LPTSTR printer_name_to_use = NULL; | 174 LPTSTR printer_name_to_use = NULL; |
| 169 std::wstring printer_name_wide; | 175 std::wstring printer_name_wide; |
| 170 if (!printer_name.empty()) { | 176 if (!printer_name.empty()) { |
| 171 printer_name_wide = UTF8ToWide(printer_name); | 177 printer_name_wide = UTF8ToWide(printer_name); |
| 172 printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str()); | 178 printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str()); |
| 173 } | 179 } |
| 174 bool ret = false; | 180 bool ret = false; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 187 } | 193 } |
| 188 bool Stop() { | 194 bool Stop() { |
| 189 watcher_.StopWatching(); | 195 watcher_.StopWatching(); |
| 190 printer_.Close(); | 196 printer_.Close(); |
| 191 printer_change_.Close(); | 197 printer_change_.Close(); |
| 192 return true; | 198 return true; |
| 193 } | 199 } |
| 194 | 200 |
| 195 // base::ObjectWatcher::Delegate method | 201 // base::ObjectWatcher::Delegate method |
| 196 virtual void OnObjectSignaled(HANDLE object) { | 202 virtual void OnObjectSignaled(HANDLE object) { |
| 203 child_process_logging::ScopedPrinterInfoSetter prn_info(printer_info_); |
| 197 DWORD change = 0; | 204 DWORD change = 0; |
| 198 FindNextPrinterChangeNotification(object, &change, NULL, NULL); | 205 FindNextPrinterChangeNotification(object, &change, NULL, NULL); |
| 199 | 206 |
| 200 if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) & | 207 if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) & |
| 201 (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) { | 208 (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) { |
| 202 // For printer connections, we get spurious change notifications with | 209 // For printer connections, we get spurious change notifications with |
| 203 // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER. | 210 // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER. |
| 204 // Ignore these. | 211 // Ignore these. |
| 205 if (change & PRINTER_CHANGE_ADD_PRINTER) { | 212 if (change & PRINTER_CHANGE_ADD_PRINTER) { |
| 206 delegate_->OnPrinterAdded(); | 213 delegate_->OnPrinterAdded(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 return ret; | 254 return ret; |
| 248 } | 255 } |
| 249 | 256 |
| 250 private: | 257 private: |
| 251 base::win::ObjectWatcher watcher_; | 258 base::win::ObjectWatcher watcher_; |
| 252 printing::ScopedPrinterHandle printer_; // The printer being watched | 259 printing::ScopedPrinterHandle printer_; // The printer being watched |
| 253 // Returned by FindFirstPrinterChangeNotifier. | 260 // Returned by FindFirstPrinterChangeNotifier. |
| 254 ScopedPrinterChangeHandle printer_change_; | 261 ScopedPrinterChangeHandle printer_change_; |
| 255 Delegate* delegate_; // Delegate to notify | 262 Delegate* delegate_; // Delegate to notify |
| 256 bool did_signal_; // DoneWaiting was called | 263 bool did_signal_; // DoneWaiting was called |
| 264 std::string printer_info_; // For crash reporting. |
| 257 }; | 265 }; |
| 258 | 266 |
| 259 // This typedef is to workaround the issue with certain versions of | 267 // This typedef is to workaround the issue with certain versions of |
| 260 // Visual Studio where it gets confused between multiple Delegate. | 268 // Visual Studio where it gets confused between multiple Delegate. |
| 261 // In this case, some compilers get confused and inherit | 269 // In this case, some compilers get confused and inherit |
| 262 // PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. | 270 // PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. |
| 263 typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; | 271 typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; |
| 264 | 272 |
| 265 class PrintSystemWin : public PrintSystem { | 273 class PrintSystemWin : public PrintSystem { |
| 266 public: | 274 public: |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 | 378 |
| 371 // PrintSystem::JobSpooler implementation. | 379 // PrintSystem::JobSpooler implementation. |
| 372 virtual bool Spool(const std::string& print_ticket, | 380 virtual bool Spool(const std::string& print_ticket, |
| 373 const FilePath& print_data_file_path, | 381 const FilePath& print_data_file_path, |
| 374 const std::string& print_data_mime_type, | 382 const std::string& print_data_mime_type, |
| 375 const std::string& printer_name, | 383 const std::string& printer_name, |
| 376 const std::string& job_title, | 384 const std::string& job_title, |
| 377 const std::vector<std::string>& tags, | 385 const std::vector<std::string>& tags, |
| 378 JobSpooler::Delegate* delegate) OVERRIDE { | 386 JobSpooler::Delegate* delegate) OVERRIDE { |
| 379 // TODO(gene): add tags handling. | 387 // TODO(gene): add tags handling. |
| 388 scoped_refptr<printing::PrintBackend> print_backend( |
| 389 printing::PrintBackend::CreateInstance(NULL)); |
| 390 child_process_logging::ScopedPrinterInfoSetter prn_info( |
| 391 print_backend->GetPrinterDriverInfo(printer_name)); |
| 380 return core_->Spool(print_ticket, print_data_file_path, | 392 return core_->Spool(print_ticket, print_data_file_path, |
| 381 print_data_mime_type, printer_name, job_title, | 393 print_data_mime_type, printer_name, job_title, |
| 382 delegate); | 394 delegate); |
| 383 } | 395 } |
| 384 | 396 |
| 385 private: | 397 private: |
| 386 // We use a Core class because we want a separate RefCountedThreadSafe | 398 // We use a Core class because we want a separate RefCountedThreadSafe |
| 387 // implementation for ServiceUtilityProcessHost::Client. | 399 // implementation for ServiceUtilityProcessHost::Client. |
| 388 class Core : public ServiceUtilityProcessHost::Client, | 400 class Core : public ServiceUtilityProcessHost::Client, |
| 389 public base::win::ObjectWatcher::Delegate { | 401 public base::win::ObjectWatcher::Delegate { |
| 390 public: | 402 public: |
| 391 Core() | 403 Core() |
| 392 : last_page_printed_(-1), | 404 : last_page_printed_(-1), |
| 393 job_id_(-1), | 405 job_id_(-1), |
| 394 delegate_(NULL), | 406 delegate_(NULL), |
| 395 saved_dc_(0), | 407 saved_dc_(0), |
| 396 should_couninit_(false) { | 408 should_couninit_(false) { |
| 397 } | 409 } |
| 398 | 410 |
| 399 ~Core() {} | 411 ~Core() {} |
| 400 | 412 |
| 401 bool Spool(const std::string& print_ticket, | 413 bool Spool(const std::string& print_ticket, |
| 402 const FilePath& print_data_file_path, | 414 const FilePath& print_data_file_path, |
| 403 const std::string& print_data_mime_type, | 415 const std::string& print_data_mime_type, |
| 404 const std::string& printer_name, | 416 const std::string& printer_name, |
| 405 const std::string& job_title, | 417 const std::string& job_title, |
| 406 JobSpooler::Delegate* delegate) { | 418 JobSpooler::Delegate* delegate) { |
| 419 scoped_refptr<printing::PrintBackend> print_backend( |
| 420 printing::PrintBackend::CreateInstance(NULL)); |
| 421 child_process_logging::ScopedPrinterInfoSetter prn_info( |
| 422 print_backend->GetPrinterDriverInfo(printer_name)); |
| 407 if (delegate_) { | 423 if (delegate_) { |
| 408 // We are already in the process of printing. | 424 // We are already in the process of printing. |
| 409 NOTREACHED(); | 425 NOTREACHED(); |
| 410 return false; | 426 return false; |
| 411 } | 427 } |
| 412 last_page_printed_ = -1; | 428 last_page_printed_ = -1; |
| 413 // We only support PDF and XPS documents for now. | 429 // We only support PDF and XPS documents for now. |
| 414 if (print_data_mime_type == "application/pdf") { | 430 if (print_data_mime_type == "application/pdf") { |
| 415 DevMode pt_dev_mode; | 431 DevMode pt_dev_mode; |
| 416 HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket, | 432 HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket, |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 handler->Start(); | 789 handler->Start(); |
| 774 } | 790 } |
| 775 | 791 |
| 776 bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) { | 792 bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) { |
| 777 return print_backend_->IsValidPrinter(printer_name); | 793 return print_backend_->IsValidPrinter(printer_name); |
| 778 } | 794 } |
| 779 | 795 |
| 780 bool PrintSystemWin::ValidatePrintTicket( | 796 bool PrintSystemWin::ValidatePrintTicket( |
| 781 const std::string& printer_name, | 797 const std::string& printer_name, |
| 782 const std::string& print_ticket_data) { | 798 const std::string& print_ticket_data) { |
| 799 child_process_logging::ScopedPrinterInfoSetter prn_info( |
| 800 print_backend_->GetPrinterDriverInfo(printer_name)); |
| 783 printing::ScopedXPSInitializer xps_initializer; | 801 printing::ScopedXPSInitializer xps_initializer; |
| 784 if (!xps_initializer.initialized()) { | 802 if (!xps_initializer.initialized()) { |
| 785 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 803 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
| 786 return false; | 804 return false; |
| 787 } | 805 } |
| 788 bool ret = false; | 806 bool ret = false; |
| 789 HPTPROVIDER provider = NULL; | 807 HPTPROVIDER provider = NULL; |
| 790 printing::XPSModule::OpenProvider(UTF8ToWide(printer_name.c_str()), | 808 printing::XPSModule::OpenProvider(UTF8ToWide(printer_name.c_str()), |
| 791 1, | 809 1, |
| 792 &provider); | 810 &provider); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 812 result_ticket_stream.get(), | 830 result_ticket_stream.get(), |
| 813 error.Receive())); | 831 error.Receive())); |
| 814 printing::XPSModule::CloseProvider(provider); | 832 printing::XPSModule::CloseProvider(provider); |
| 815 } | 833 } |
| 816 return ret; | 834 return ret; |
| 817 } | 835 } |
| 818 | 836 |
| 819 bool PrintSystemWin::GetJobDetails(const std::string& printer_name, | 837 bool PrintSystemWin::GetJobDetails(const std::string& printer_name, |
| 820 PlatformJobId job_id, | 838 PlatformJobId job_id, |
| 821 PrintJobDetails *job_details) { | 839 PrintJobDetails *job_details) { |
| 840 child_process_logging::ScopedPrinterInfoSetter prn_info( |
| 841 print_backend_->GetPrinterDriverInfo(printer_name)); |
| 822 DCHECK(job_details); | 842 DCHECK(job_details); |
| 823 printing::ScopedPrinterHandle printer_handle; | 843 printing::ScopedPrinterHandle printer_handle; |
| 824 std::wstring printer_name_wide = UTF8ToWide(printer_name); | 844 std::wstring printer_name_wide = UTF8ToWide(printer_name); |
| 825 OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), | 845 OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), |
| 826 printer_handle.Receive(), NULL); | 846 printer_handle.Receive(), NULL); |
| 827 DCHECK(printer_handle.IsValid()); | 847 DCHECK(printer_handle.IsValid()); |
| 828 bool ret = false; | 848 bool ret = false; |
| 829 if (printer_handle.IsValid()) { | 849 if (printer_handle.IsValid()) { |
| 830 DWORD bytes_needed = 0; | 850 DWORD bytes_needed = 0; |
| 831 GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed); | 851 GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string)); | 915 RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string)); |
| 896 return ret; | 916 return ret; |
| 897 } | 917 } |
| 898 | 918 |
| 899 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( | 919 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( |
| 900 const base::DictionaryValue* print_system_settings) { | 920 const base::DictionaryValue* print_system_settings) { |
| 901 return new PrintSystemWin; | 921 return new PrintSystemWin; |
| 902 } | 922 } |
| 903 | 923 |
| 904 } // namespace cloud_print | 924 } // namespace cloud_print |
| OLD | NEW |