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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PRINTING_BACKEND_WIN_HELPER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PRINTING_BACKEND_WIN_HELPER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <objidl.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <prntvpt.h>
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <winspool.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <xpsprint.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string16.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printing_export.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These are helper functions for dealing with Windows Printing.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PRINTING_EXPORT PrinterBasicInfo;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrinterHandleTraits {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef HANDLE Handle;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool CloseHandle(HANDLE handle) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ::ClosePrinter(handle) != FALSE;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsHandleValid(HANDLE handle) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return handle != NULL;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HANDLE NullHandle() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(PrinterHandleTraits);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ScopedPrinterHandle
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public base::win::GenericScopedHandle<PrinterHandleTraits,
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            base::win::VerifierTraits> {
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool OpenPrinter(const wchar_t* printer) {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HANDLE temp_handle;
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // ::OpenPrinter may return error but assign some value into handle.
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (::OpenPrinter(const_cast<LPTSTR>(printer), &temp_handle, NULL)) {
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Set(temp_handle);
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IsValid();
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef base::win::GenericScopedHandle<PrinterHandleTraits,
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                         base::win::VerifierTraits> Base;
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PrinterChangeHandleTraits {
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef HANDLE Handle;
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool CloseHandle(HANDLE handle) {
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ::FindClosePrinterChangeNotification(handle);
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool IsHandleValid(HANDLE handle) {
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return handle != NULL;
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static HANDLE NullHandle() {
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(PrinterChangeHandleTraits);
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef base::win::GenericScopedHandle<PrinterChangeHandleTraits,
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       base::win::DummyVerifierTraits>
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedPrinterChangeHandle;
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wrapper class to wrap the XPS APIs (PTxxx APIs). This is needed because these
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// APIs are not available by default on XP. We could delayload prntvpt.dll but
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this would mean having to add that to every binary that links with
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// printing.lib (which is a LOT of binaries). So choosing the GetProcAddress
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// route instead).
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PRINTING_EXPORT XPSModule {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All the other methods can ONLY be called after a successful call to Init.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Init can be called many times and by multiple threads.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Init();
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static HRESULT OpenProvider(const base::string16& printer_name,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DWORD version,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              HPTPROVIDER* provider);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT GetPrintCapabilities(HPTPROVIDER provider,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      IStream* print_ticket,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      IStream* capabilities,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      BSTR* error_message);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT ConvertDevModeToPrintTicket(HPTPROVIDER provider,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             ULONG devmode_size_in_bytes,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             PDEVMODE devmode,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             EPrintTicketScope scope,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             IStream* print_ticket);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT ConvertPrintTicketToDevMode(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HPTPROVIDER provider,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IStream* print_ticket,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EDefaultDevmodeType base_devmode_type,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EPrintTicketScope scope,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ULONG* devmode_byte_count,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PDEVMODE* devmode,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BSTR* error_message);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT MergeAndValidatePrintTicket(HPTPROVIDER provider,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             IStream* base_ticket,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             IStream* delta_ticket,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             EPrintTicketScope scope,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             IStream* result_ticket,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             BSTR* error_message);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT ReleaseMemory(PVOID buffer);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT CloseProvider(HPTPROVIDER provider);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XPSModule() { }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool InitImpl();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See comments in cc file explaining why we need this.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PRINTING_EXPORT ScopedXPSInitializer {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedXPSInitializer();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedXPSInitializer();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool initialized() const { return initialized_; }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool initialized_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wrapper class to wrap the XPS Print APIs (these are different from the PTxxx
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which deal with the XML Print Schema). This is needed because these
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// APIs are only available on Windows 7 and higher.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PRINTING_EXPORT XPSPrintModule {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All the other methods can ONLY be called after a successful call to Init.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Init can be called many times and by multiple threads.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Init();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HRESULT StartXpsPrintJob(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const LPCWSTR printer_name,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const LPCWSTR job_name,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const LPCWSTR output_file_name,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE progress_event,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE completion_event,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UINT8* printable_pages_on,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UINT32 printable_pages_on_count,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IXpsPrintJob **xps_print_job,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IXpsPrintJobStream **document_stream,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IXpsPrintJobStream **print_ticket_stream);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XPSPrintModule() { }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool InitImpl();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRINTING_EXPORT bool InitBasicPrinterInfo(HANDLE printer,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          PrinterBasicInfo* printer_info);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRINTING_EXPORT std::string GetDriverInfo(HANDLE printer);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode(
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& printer_name,
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& print_ticket);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates default DEVMODE and sets color option. Some devices need special
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// workaround for color.
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor(
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HANDLE printer,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& printer_name,
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool color);
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates new DEVMODE. If |in| is not NULL copy settings from there.
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    HANDLE printer,
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DEVMODE* in);
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Prompts for new DEVMODE. If |in| is not NULL copy settings from there.
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode(
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HANDLE printer,
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::string16& printer_name,
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DEVMODE* in,
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HWND window,
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool* canceled);
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace printing
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // PRINTING_BACKEND_WIN_HELPER_H_
200