15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/service/cloud_print/print_system.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/command_line.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/json/json_writer.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/object_watcher.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/win/scoped_bstr.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/win/scoped_comptr.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/win/scoped_hdc.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/common/cloud_print/cloud_print_cdd_conversion.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/cloud_print/cloud_print_constants.h" 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/common/crash_keys.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/service/cloud_print/cdd_conversion_win.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/service/service_process.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/service/service_utility_process_host.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/backend/win_helper.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "printing/emf_win.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "printing/page_range.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "printing/pdf_render_settings.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "printing/printing_utils.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/gfx/geometry/rect.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace cloud_print { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSystemWatcherWin() 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(NULL), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_signal_(false) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PrintSystemWatcherWin() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Delegate { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Delegate() {} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPrinterAdded() = 0; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPrinterDeleted() = 0; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPrinterChanged() = 0; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnJobChanged() = 0; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Start(const std::string& printer_name, Delegate* delegate) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<printing::PrintBackend> print_backend( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing::PrintBackend::CreateInstance(NULL)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_info_ = print_backend->GetPrinterDriverInfo(printer_name); 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) crash_keys::ScopedPrinterInfo crash_key(printer_info_); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = delegate; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An empty printer name means watch the current server, we need to pass 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULL to OpenPrinter. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPTSTR printer_name_to_use = NULL; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring printer_name_wide; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!printer_name.empty()) { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printer_name_wide = base::UTF8ToWide(printer_name); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str()); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = false; 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (printer_.OpenPrinter(printer_name_to_use)) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_change_.Set(FindFirstPrinterChangeNotification( 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci printer_.Get(), PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printer_change_.IsValid()) { 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ret = watcher_.StartWatching(printer_change_.Get(), this); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ret) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Stop() { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watcher_.StopWatching(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_.Close(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_change_.Close(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // base::ObjectWatcher::Delegate method 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnObjectSignaled(HANDLE object) { 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) crash_keys::ScopedPrinterInfo crash_key(printer_info_); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD change = 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindNextPrinterChangeNotification(object, &change, NULL, NULL); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) & 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For printer connections, we get spurious change notifications with 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore these. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change & PRINTER_CHANGE_ADD_PRINTER) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnPrinterAdded(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (change & PRINTER_CHANGE_DELETE_PRINTER) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnPrinterDeleted(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (change & PRINTER_CHANGE_SET_PRINTER) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnPrinterChanged(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (change & PRINTER_CHANGE_JOB) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnJobChanged(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci watcher_.StartWatching(printer_change_.Get(), this); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(printer_info); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return InitBasicPrinterInfo(printer_.Get(), printer_info); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ObjectWatcher watcher_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing::ScopedPrinterHandle printer_; // The printer being watched 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returned by FindFirstPrinterChangeNotifier. 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) printing::ScopedPrinterChangeHandle printer_change_; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate_; // Delegate to notify 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool did_signal_; // DoneWaiting was called 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string printer_info_; // For crash reporting. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PrintServerWatcherWin 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : public PrintSystem::PrintServerWatcher, 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public PrintSystemWatcherWin::Delegate { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintServerWatcherWin() : delegate_(NULL) {} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // PrintSystem::PrintServerWatcher implementation. 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool StartWatching( 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintSystem::PrintServerWatcher::Delegate* delegate) OVERRIDE{ 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_ = delegate; 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return watcher_.Start(std::string(), this); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool StopWatching() OVERRIDE{ 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ret = watcher_.Stop(); 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_ = NULL; 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ret; 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // PrintSystemWatcherWin::Delegate implementation. 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnPrinterAdded() OVERRIDE { 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnPrinterAdded(); 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnPrinterDeleted() OVERRIDE {} 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnPrinterChanged() OVERRIDE {} 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnJobChanged() OVERRIDE {} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected: 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~PrintServerWatcherWin() {} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintSystem::PrintServerWatcher::Delegate* delegate_; 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintSystemWatcherWin watcher_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherWin); 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PrinterWatcherWin 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : public PrintSystem::PrinterWatcher, 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public PrintSystemWatcherWin::Delegate { 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit PrinterWatcherWin(const std::string& printer_name) 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : printer_name_(printer_name), 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_(NULL) { 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // PrintSystem::PrinterWatcher implementation. 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool StartWatching( 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE { 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_ = delegate; 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return watcher_.Start(printer_name_, this); 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool StopWatching() OVERRIDE { 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ret = watcher_.Stop(); 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_ = NULL; 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ret; 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool GetCurrentPrinterInfo( 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) printing::PrinterBasicInfo* printer_info) OVERRIDE { 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return watcher_.GetCurrentPrinterInfo(printer_info); 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // PrintSystemWatcherWin::Delegate implementation. 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnPrinterAdded() OVERRIDE { 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTREACHED(); 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnPrinterDeleted() OVERRIDE { 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnPrinterDeleted(); 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnPrinterChanged() OVERRIDE { 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnPrinterChanged(); 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnJobChanged() OVERRIDE { 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnJobChanged(); 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected: 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~PrinterWatcherWin() {} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string printer_name_; 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintSystem::PrinterWatcher::Delegate* delegate_; 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrintSystemWatcherWin watcher_; 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PrinterWatcherWin); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class JobSpoolerWin : public PrintSystem::JobSpooler { 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JobSpoolerWin() : core_(new Core) {} 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PrintSystem::JobSpooler implementation. 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool Spool(const std::string& print_ticket, 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket_mime_type, 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& print_data_file_path, 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_data_mime_type, 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& job_title, 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<std::string>& tags, 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JobSpooler::Delegate* delegate) OVERRIDE { 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(gene): add tags handling. 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<printing::PrintBackend> print_backend( 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::PrintBackend::CreateInstance(NULL)); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crash_keys::ScopedPrinterInfo crash_key( 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_backend->GetPrinterDriverInfo(printer_name)); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return core_->Spool(print_ticket, print_ticket_mime_type, 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_data_file_path, print_data_mime_type, 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printer_name, job_title, delegate); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~JobSpoolerWin() {} 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We use a Core class because we want a separate RefCountedThreadSafe 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // implementation for ServiceUtilityProcessHost::Client. 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class Core : public ServiceUtilityProcessHost::Client, 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public base::win::ObjectWatcher::Delegate { 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Core() : job_id_(-1), delegate_(NULL), saved_dc_(0) {} 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ~Core() {} 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool Spool(const std::string& print_ticket, 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket_mime_type, 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& print_data_file_path, 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_data_mime_type, 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& job_title, 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JobSpooler::Delegate* delegate) { 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (delegate_) { 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We are already in the process of printing. 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 printer_wide = base::UTF8ToWide(printer_name); 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We only support PDF and XPS documents for now. 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (print_data_mime_type == kContentTypePDF) { 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (print_ticket_mime_type == kContentTypeJSON) { 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dev_mode = CjtToDevMode(printer_wide, print_ticket); 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(print_ticket_mime_type == kContentTypeXML); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dev_mode = printing::XpsTicketToDevMode(printer_wide, print_ticket); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!dev_mode) { 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HDC dc = CreateDC(L"WINSPOOL", printer_wide.c_str(), NULL, 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dev_mode.get()); 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!dc) { 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DOCINFO di = {0}; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) di.cbSize = sizeof(DOCINFO); 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 doc_name = base::UTF8ToUTF16(job_title); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name); 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) di.lpszDocName = doc_name.c_str(); 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_id_ = StartDoc(dc, &di); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (job_id_ <= 0) 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printer_dc_.Set(dc); 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_dc_ = SaveDC(printer_dc_.Get()); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_data_file_path_ = print_data_file_path; 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_ = delegate; 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RenderPDFPages(); 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (print_data_mime_type == kContentTypeXPS) { 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(print_ticket_mime_type == kContentTypeXML); 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool ret = PrintXPSDocument(printer_name, 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_title, 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_data_file_path, 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ret) 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_ = delegate; 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ret; 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PreparePageDCForPrinting(HDC, double scale_factor) { 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED); 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Setup the matrix to translate and scale to the right place. Take in 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // account the scale factor. 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that the printing output is relative to printable area of 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the page. That is 0,0 is offset by PHYSICALOFFSETX/Y from the page. 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int offset_x = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETX); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int offset_y = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETY); 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) XFORM xform = {0}; 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xform.eDx = static_cast<float>(-offset_x); 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xform.eDy = static_cast<float>(-offset_y); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xform.eM11 = xform.eM22 = 1.0 / scale_factor; 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetWorldTransform(printer_dc_.Get(), &xform); 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ServiceUtilityProcessHost::Client implementation. 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnRenderPDFPagesToMetafilePageDone( 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci double scale_factor, 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const printing::MetafilePlayer& emf) OVERRIDE { 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PreparePageDCForPrinting(printer_dc_.Get(), scale_factor); 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ::StartPage(printer_dc_.Get()); 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci emf.SafePlayback(printer_dc_.Get()); 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ::EndPage(printer_dc_.Get()); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // ServiceUtilityProcessHost::Client implementation. 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnRenderPDFPagesToMetafileDone(bool success) OVERRIDE { 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintJobDone(success); 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnChildDied() OVERRIDE { PrintJobDone(false); } 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // base::win::ObjectWatcher::Delegate implementation. 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnObjectSignaled(HANDLE object) OVERRIDE { 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(xps_print_job_); 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(object == job_progress_event_.Get()); 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResetEvent(job_progress_event_.Get()); 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!delegate_) 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) XPS_JOB_STATUS job_status = {0}; 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xps_print_job_->GetJobStatus(&job_status); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((job_status.completion == XPS_JOB_CANCELLED) || 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (job_status.completion == XPS_JOB_FAILED)) { 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->OnJobSpoolFailed(); 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (job_status.jobId || 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (job_status.completion == XPS_JOB_COMPLETED)) { 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note: In the case of the XPS document being printed to the 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Microsoft XPS Document Writer, it seems to skip spooling the job 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and goes to the completed state without ever assigning a job id. 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->OnJobSpoolSucceeded(job_status.jobId); 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_progress_watcher_.StopWatching(); 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_progress_watcher_.StartWatching(job_progress_event_.Get(), this); 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Helper class to allow PrintXPSDocument() to have multiple exits. 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class PrintJobCanceler { 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit PrintJobCanceler( 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IXpsPrintJob>* job_ptr) 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : job_ptr_(job_ptr) { 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ~PrintJobCanceler() { 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (job_ptr_ && *job_ptr_) { 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*job_ptr_)->Cancel(); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_ptr_->Release(); 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void reset() { job_ptr_ = NULL; } 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IXpsPrintJob>* job_ptr_; 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PrintJobCanceler); 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void PrintJobDone(bool success) { 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If there is no delegate, then there is nothing pending to process. 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!delegate_) 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RestoreDC(printer_dc_.Get(), saved_dc_); 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EndDoc(printer_dc_.Get()); 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (success) { 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->OnJobSpoolSucceeded(job_id_); 4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->OnJobSpoolFailed(); 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_ = NULL; 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void RenderPDFPages() { 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX); 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int dc_width = GetDeviceCaps(printer_dc_.Get(), PHYSICALWIDTH); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int dc_height = GetDeviceCaps(printer_dc_.Get(), PHYSICALHEIGHT); 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect render_area(0, 0, dc_width, dc_height); 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_service_process->io_thread()->message_loop_proxy()->PostTask( 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox, 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this, 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci print_data_file_path_, 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_area, 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci printer_dpi, 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::MessageLoopProxy::current())); 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called on the service process IO thread. 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void RenderPDFPagesInSandbox(const base::FilePath& pdf_path, 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Rect& render_area, 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int render_dpi, 4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::MessageLoopProxy>& 4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_message_loop_proxy) { 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(g_service_process->io_thread()->message_loop_proxy()-> 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BelongsToCurrentThread()); 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ServiceUtilityProcessHost> utility_host( 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ServiceUtilityProcessHost(this, client_message_loop_proxy)); 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(gene): For now we disabling autorotation for CloudPrinting. 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Landscape/Portrait setting is passed in the print ticket and 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // server is generating portrait PDF always. 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We should enable autorotation once server will be able to generate 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PDF that matches paper size and orientation. 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (utility_host->StartRenderPDFPagesToMetafile( 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pdf_path, 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci printing::PdfRenderSettings(render_area, render_dpi, false))) { 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The object will self-destruct when the child process dies. 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) utility_host.release(); 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_message_loop_proxy->PostTask( 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, base::Bind(&Core::PrintJobDone, this, false)); 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool PrintXPSDocument(const std::string& printer_name, 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& job_title, 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& print_data_file_path, 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket) { 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!printing::XPSPrintModule::Init()) 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!job_progress_event_.Get()) 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrintJobCanceler job_canceler(&xps_print_job_); 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream; 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream; 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FAILED(printing::XPSPrintModule::StartXpsPrintJob( 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToWide(printer_name).c_str(), 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToWide(job_title).c_str(), 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, job_progress_event_.Get(), NULL, NULL, NULL, 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xps_print_job_.Receive(), doc_stream.Receive(), 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket_stream.Receive()))) 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ULONG print_bytes_written = 0; 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FAILED(print_ticket_stream->Write(print_ticket.c_str(), 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket.length(), 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &print_bytes_written))) 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(print_ticket.length(), print_bytes_written); 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FAILED(print_ticket_stream->Close())) 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string document_data; 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ReadFileToString(print_data_file_path, &document_data); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ULONG doc_bytes_written = 0; 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FAILED(doc_stream->Write(document_data.c_str(), 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) document_data.length(), 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &doc_bytes_written))) 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(document_data.length(), doc_bytes_written); 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FAILED(doc_stream->Close())) 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_progress_watcher_.StartWatching(job_progress_event_.Get(), this); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) job_canceler.reset(); 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PlatformJobId job_id_; 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrintSystem::JobSpooler::Delegate* delegate_; 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int saved_dc_; 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedCreateDC printer_dc_; 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath print_data_file_path_; 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedHandle job_progress_event_; 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ObjectWatcher job_progress_watcher_; 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_; 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<Core> core_; 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin); 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A helper class to handle the response from the utility process to the 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// request to fetch printer capabilities and defaults. 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PrinterCapsHandler : public ServiceUtilityProcessHost::Client { 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrinterCapsHandler( 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PrintSystem::PrinterCapsAndDefaultsCallback& callback) 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : printer_name_(printer_name), callback_(callback) { 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ServiceUtilityProcessHost::Client implementation. 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnChildDied() OVERRIDE { 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnGetPrinterCapsAndDefaults(false, printer_name_, 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::PrinterCapsAndDefaults()); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnGetPrinterCapsAndDefaults( 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool succeeded, 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const printing::PrinterCapsAndDefaults& caps_and_defaults) OVERRIDE { 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(succeeded, printer_name, caps_and_defaults); 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Reset(); 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Release(); 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnGetPrinterSemanticCapsAndDefaults( 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool succeeded, 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const printing::PrinterSemanticCapsAndDefaults& semantic_info) OVERRIDE { 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::PrinterCapsAndDefaults printer_info; 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (succeeded) { 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printer_info.caps_mime_type = kContentTypeJSON; 54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<base::DictionaryValue> description( 54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PrinterSemanticCapsAndDefaultsToCdd(semantic_info)); 54946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (description) { 55046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::JSONWriter::WriteWithOptions( 55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) description.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, 55246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &printer_info.printer_capabilities); 55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(succeeded, printer_name, printer_info); 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Reset(); 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Release(); 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void StartGetPrinterCapsAndDefaults() { 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_service_process->io_thread()->message_loop_proxy()->PostTask( 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PrinterCapsHandler::GetPrinterCapsAndDefaultsImpl, this, 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoopProxy::current())); 5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void StartGetPrinterSemanticCapsAndDefaults() { 5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_service_process->io_thread()->message_loop_proxy()->PostTask( 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PrinterCapsHandler::GetPrinterSemanticCapsAndDefaultsImpl, 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, base::MessageLoopProxy::current())); 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void GetPrinterCapsAndDefaultsImpl( 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_message_loop_proxy) { 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(g_service_process->io_thread()->message_loop_proxy()-> 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BelongsToCurrentThread()); 5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ServiceUtilityProcessHost> utility_host( 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ServiceUtilityProcessHost(this, client_message_loop_proxy)); 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (utility_host->StartGetPrinterCapsAndDefaults(printer_name_)) { 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The object will self-destruct when the child process dies. 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) utility_host.release(); 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_message_loop_proxy->PostTask( 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PrinterCapsHandler::OnChildDied, this)); 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void GetPrinterSemanticCapsAndDefaultsImpl( 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_message_loop_proxy) { 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(g_service_process->io_thread()->message_loop_proxy()-> 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BelongsToCurrentThread()); 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ServiceUtilityProcessHost> utility_host( 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ServiceUtilityProcessHost(this, client_message_loop_proxy)); 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (utility_host->StartGetPrinterSemanticCapsAndDefaults(printer_name_)) { 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The object will self-destruct when the child process dies. 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) utility_host.release(); 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_message_loop_proxy->PostTask( 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PrinterCapsHandler::OnChildDied, this)); 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string printer_name_; 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrintSystem::PrinterCapsAndDefaultsCallback callback_; 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PrintSystemWin : public PrintSystem { 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrintSystemWin(); 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PrintSystem implementation. 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual PrintSystemResult Init() OVERRIDE; 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual PrintSystem::PrintSystemResult EnumeratePrinters( 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::PrinterList* printer_list) OVERRIDE; 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void GetPrinterCapsAndDefaults( 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PrinterCapsAndDefaultsCallback& callback) OVERRIDE; 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool IsValidPrinter(const std::string& printer_name) OVERRIDE; 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool ValidatePrintTicket( 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket_data, 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket_data_mime_type) OVERRIDE; 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool GetJobDetails(const std::string& printer_name, 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PlatformJobId job_id, 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrintJobDetails *job_details) OVERRIDE; 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher() OVERRIDE; 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name) OVERRIDE; 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual PrintSystem::JobSpooler* CreateJobSpooler() OVERRIDE; 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool UseCddAndCjt() OVERRIDE; 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual std::string GetSupportedMimeTypes() OVERRIDE; 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string PrintSystemWin::GetPrinterDriverInfo( 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name) const; 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<printing::PrintBackend> print_backend_; 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool use_cdd_; 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PrintSystemWin); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PrintSystemWin::PrintSystemWin() : use_cdd_(true) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_backend_ = printing::PrintBackend::CreateInstance(NULL); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PrintSystem::PrintSystemResult PrintSystemWin::Init() { 653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) use_cdd_ = !CommandLine::ForCurrentProcess()->HasSwitch( 654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switches::kEnableCloudPrintXps); 655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!use_cdd_) 657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) use_cdd_ = !printing::XPSModule::Init(); 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!use_cdd_) { 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HPTPROVIDER provider = NULL; 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HRESULT hr = printing::XPSModule::OpenProvider(L"", 1, &provider); 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (provider) 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::XPSModule::CloseProvider(provider); 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use cdd if error is different from expected. 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) use_cdd_ = (hr != HRESULT_FROM_WIN32(ERROR_INVALID_PRINTER_NAME)); 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return PrintSystemResult(true, std::string()); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystem::PrintSystemResult PrintSystemWin::EnumeratePrinters( 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing::PrinterList* printer_list) { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = print_backend_->EnumeratePrinters(printer_list); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PrintSystemResult(ret, std::string()); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrintSystemWin::GetPrinterCapsAndDefaults( 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PrinterCapsAndDefaultsCallback& callback) { 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Launch as child process to retrieve the capabilities and defaults because 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this involves invoking a printer driver DLL and crashes have been known to 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // occur. 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrinterCapsHandler* handler = new PrinterCapsHandler(printer_name, callback); 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handler->AddRef(); 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (use_cdd_) 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handler->StartGetPrinterSemanticCapsAndDefaults(); 6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handler->StartGetPrinterCapsAndDefaults(); 6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return print_backend_->IsValidPrinter(printer_name); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PrintSystemWin::ValidatePrintTicket( 6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& printer_name, 6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket_data, 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& print_ticket_data_mime_type) { 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crash_keys::ScopedPrinterInfo crash_key(GetPrinterDriverInfo(printer_name)); 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (use_cdd_) { 7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return print_ticket_data_mime_type == kContentTypeJSON && 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IsValidCjt(print_ticket_data); 7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(print_ticket_data_mime_type == kContentTypeXML); 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::ScopedXPSInitializer xps_initializer; 7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!xps_initializer.initialized()) { 7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) 7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool ret = false; 7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HPTPROVIDER provider = NULL; 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::XPSModule::OpenProvider(base::UTF8ToWide(printer_name), 1, 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &provider); 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (provider) { 7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IStream> print_ticket_stream; 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateStreamOnHGlobal(NULL, TRUE, print_ticket_stream.Receive()); 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ULONG bytes_written = 0; 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket_stream->Write(print_ticket_data.c_str(), 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket_data.length(), 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &bytes_written); 7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(bytes_written == print_ticket_data.length()); 7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LARGE_INTEGER pos = {0}; 7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ULARGE_INTEGER new_pos = {0}; 7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket_stream->Seek(pos, STREAM_SEEK_SET, &new_pos); 7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedBstr error; 7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::win::ScopedComPtr<IStream> result_ticket_stream; 7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateStreamOnHGlobal(NULL, TRUE, result_ticket_stream.Receive()); 7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ret = SUCCEEDED(printing::XPSModule::MergeAndValidatePrintTicket( 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider, 7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print_ticket_stream.get(), 7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kPTJobScope, 7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result_ticket_stream.get(), 7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error.Receive())); 7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing::XPSModule::CloseProvider(provider); 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ret; 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintSystemWin::GetJobDetails(const std::string& printer_name, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformJobId job_id, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintJobDetails *job_details) { 745d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) crash_keys::ScopedPrinterInfo crash_key( 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_backend_->GetPrinterDriverInfo(printer_name)); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(job_details); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing::ScopedPrinterHandle printer_handle; 7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::wstring printer_name_wide = base::UTF8ToWide(printer_name); 7507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) printer_handle.OpenPrinter(printer_name_wide.c_str()); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(printer_handle.IsValid()); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = false; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printer_handle.IsValid()) { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD bytes_needed = 0; 7551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetJob(printer_handle.Get(), job_id, 1, NULL, 0, &bytes_needed); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD last_error = GetLastError(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ERROR_INVALID_PARAMETER != last_error) { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ERROR_INVALID_PARAMETER normally means that the job id is not valid. 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(last_error == ERROR_INSUFFICIENT_BUFFER); 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<BYTE[]> job_info_buffer(new BYTE[bytes_needed]); 7611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (GetJob(printer_handle.Get(), job_id, 1, job_info_buffer.get(), 7621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bytes_needed, &bytes_needed)) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JOB_INFO_1 *job_info = 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<JOB_INFO_1 *>(job_info_buffer.get()); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (job_info->pStatus) { 7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WideToUTF8(job_info->pStatus, wcslen(job_info->pStatus), 7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &job_details->status_message); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_details->platform_status_flags = job_info->Status; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((job_info->Status & JOB_STATUS_COMPLETE) || 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (job_info->Status & JOB_STATUS_PRINTED)) { 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_details->status = PRINT_JOB_STATUS_COMPLETED; 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (job_info->Status & JOB_STATUS_ERROR) { 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_details->status = PRINT_JOB_STATUS_ERROR; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_details->status = PRINT_JOB_STATUS_IN_PROGRESS; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_details->total_pages = job_info->TotalPages; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job_details->pages_printed = job_info->PagesPrinted; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = true; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystem::PrintServerWatcher* 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystemWin::CreatePrintServerWatcher() { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PrintServerWatcherWin(); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher( 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& printer_name) { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!printer_name.empty()); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PrinterWatcherWin(printer_name); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PrintSystem::JobSpooler* PrintSystemWin::CreateJobSpooler() { 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new JobSpoolerWin(); 8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PrintSystemWin::UseCddAndCjt() { 8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return use_cdd_; 8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string PrintSystemWin::GetSupportedMimeTypes() { 8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string result; 8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!use_cdd_) { 8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = kContentTypeXPS; 8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result += ","; 8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result += kContentTypePDF; 8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result; 8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string PrintSystemWin::GetPrinterDriverInfo( 817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& printer_name) const { 818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return print_backend_->GetPrinterDriverInfo(printer_name); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_refptr<PrintSystem> PrintSystem::CreateInstance( 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* print_system_settings) { 8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new PrintSystemWin; 8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace cloud_print 829