print_system_win.cc revision f2477e01787aa58f445919b809d89e252beef54f
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)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/service/cloud_print/print_system_win.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/object_watcher.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/common/crash_keys.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/backend/win_helper.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace cloud_print {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintSystemWatcherWin()
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : delegate_(NULL),
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        did_signal_(false) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PrintSystemWatcherWin() {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Stop();
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Delegate {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate() {}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnPrinterAdded() = 0;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnPrinterDeleted() = 0;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnPrinterChanged() = 0;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnJobChanged() = 0;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Start(const std::string& printer_name, Delegate* delegate) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<printing::PrintBackend> print_backend(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printing::PrintBackend::CreateInstance(NULL));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer_info_ = print_backend->GetPrinterDriverInfo(printer_name);
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    crash_keys::ScopedPrinterInfo crash_key(printer_info_);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = delegate;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // An empty printer name means watch the current server, we need to pass
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NULL to OpenPrinter.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LPTSTR printer_name_to_use = NULL;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring printer_name_wide;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!printer_name.empty()) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer_name_wide = UTF8ToWide(printer_name);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ret = false;
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (printer_.OpenPrinter(printer_name_to_use)) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer_change_.Set(FindFirstPrinterChangeNotification(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          printer_, PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (printer_change_.IsValid()) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = watcher_.StartWatching(printer_change_, this);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ret) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Stop();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ret;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Stop() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    watcher_.StopWatching();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer_.Close();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer_change_.Close();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // base::ObjectWatcher::Delegate method
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnObjectSignaled(HANDLE object) {
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    crash_keys::ScopedPrinterInfo crash_key(printer_info_);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD change = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FindNextPrinterChangeNotification(object, &change, NULL, NULL);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) &
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For printer connections, we get spurious change notifications with
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ignore these.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (change & PRINTER_CHANGE_ADD_PRINTER) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnPrinterAdded();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (change & PRINTER_CHANGE_DELETE_PRINTER) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnPrinterDeleted();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (change & PRINTER_CHANGE_SET_PRINTER) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnPrinterChanged();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (change & PRINTER_CHANGE_JOB) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnJobChanged();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    watcher_.StartWatching(printer_change_, this);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(printer_info);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return InitBasicPrinterInfo(printer_, printer_info);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ObjectWatcher watcher_;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing::ScopedPrinterHandle printer_;  // The printer being watched
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returned by FindFirstPrinterChangeNotifier.
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  printing::ScopedPrinterChangeHandle printer_change_;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Delegate* delegate_;           // Delegate to notify
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_signal_;              // DoneWaiting was called
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string printer_info_;     // For crash reporting.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PrintServerWatcherWin
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  : public PrintSystem::PrintServerWatcher,
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public PrintSystemWatcherWin::Delegate {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PrintServerWatcherWin() : delegate_(NULL) {}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // PrintSystem::PrintServerWatcher implementation.
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool StartWatching(
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PrintSystem::PrintServerWatcher::Delegate* delegate) OVERRIDE{
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_ = delegate;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return watcher_.Start(std::string(), this);
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool StopWatching() OVERRIDE{
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool ret = watcher_.Stop();
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_ = NULL;
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return ret;
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // PrintSystemWatcherWin::Delegate implementation.
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnPrinterAdded() OVERRIDE {
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_->OnPrinterAdded();
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnPrinterDeleted() OVERRIDE {}
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnPrinterChanged() OVERRIDE {}
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnJobChanged() OVERRIDE {}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  protected:
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~PrintServerWatcherWin() {}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PrintSystem::PrintServerWatcher::Delegate* delegate_;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PrintSystemWatcherWin watcher_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherWin);
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PrinterWatcherWin
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : public PrintSystem::PrinterWatcher,
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      public PrintSystemWatcherWin::Delegate {
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit PrinterWatcherWin(const std::string& printer_name)
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : printer_name_(printer_name),
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(NULL) {
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // PrintSystem::PrinterWatcher implementation.
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool StartWatching(
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE {
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_ = delegate;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return watcher_.Start(printer_name_, this);
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool StopWatching() OVERRIDE {
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool ret = watcher_.Stop();
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_ = NULL;
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return ret;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool GetCurrentPrinterInfo(
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      printing::PrinterBasicInfo* printer_info) OVERRIDE {
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return watcher_.GetCurrentPrinterInfo(printer_info);
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // PrintSystemWatcherWin::Delegate implementation.
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnPrinterAdded() OVERRIDE {
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnPrinterDeleted() OVERRIDE {
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_->OnPrinterDeleted();
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnPrinterChanged() OVERRIDE {
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_->OnPrinterChanged();
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnJobChanged() OVERRIDE {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_->OnJobChanged();
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  protected:
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~PrinterWatcherWin() {}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string printer_name_;
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PrintSystem::PrinterWatcher::Delegate* delegate_;
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PrintSystemWatcherWin watcher_;
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PrinterWatcherWin);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystemWin::PrintSystemWin() {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print_backend_ = printing::PrintBackend::CreateInstance(NULL);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PrintSystemWin::~PrintSystemWin() {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystem::PrintSystemResult PrintSystemWin::EnumeratePrinters(
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printing::PrinterList* printer_list) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret = print_backend_->EnumeratePrinters(printer_list);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PrintSystemResult(ret, std::string());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return print_backend_->IsValidPrinter(printer_name);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintSystemWin::GetJobDetails(const std::string& printer_name,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   PlatformJobId job_id,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   PrintJobDetails *job_details) {
222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  crash_keys::ScopedPrinterInfo crash_key(
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      print_backend_->GetPrinterDriverInfo(printer_name));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(job_details);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing::ScopedPrinterHandle printer_handle;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring printer_name_wide = UTF8ToWide(printer_name);
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  printer_handle.OpenPrinter(printer_name_wide.c_str());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(printer_handle.IsValid());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret = false;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (printer_handle.IsValid()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD bytes_needed = 0;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD last_error = GetLastError();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ERROR_INVALID_PARAMETER != last_error) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ERROR_INVALID_PARAMETER normally means that the job id is not valid.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(last_error == ERROR_INSUFFICIENT_BUFFER);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<BYTE[]> job_info_buffer(new BYTE[bytes_needed]);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (GetJob(printer_handle, job_id, 1, job_info_buffer.get(), bytes_needed,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                &bytes_needed)) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        JOB_INFO_1 *job_info =
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            reinterpret_cast<JOB_INFO_1 *>(job_info_buffer.get());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (job_info->pStatus) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          WideToUTF8(job_info->pStatus, wcslen(job_info->pStatus),
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     &job_details->status_message);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        job_details->platform_status_flags = job_info->Status;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((job_info->Status & JOB_STATUS_COMPLETE) ||
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (job_info->Status & JOB_STATUS_PRINTED)) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          job_details->status = PRINT_JOB_STATUS_COMPLETED;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (job_info->Status & JOB_STATUS_ERROR) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          job_details->status = PRINT_JOB_STATUS_ERROR;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          job_details->status = PRINT_JOB_STATUS_IN_PROGRESS;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        job_details->total_pages = job_info->TotalPages;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        job_details->pages_printed = job_info->PagesPrinted;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = true;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystem::PrintServerWatcher*
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystemWin::CreatePrintServerWatcher() {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PrintServerWatcherWin();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& printer_name) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!printer_name.empty());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PrinterWatcherWin(printer_name);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string PrintSystemWin::GetPrinterDriverInfo(
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& printer_name) const {
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return print_backend_->GetPrinterDriverInfo(printer_name);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace cloud_print
281