1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PRINTING_BACKEND_WIN_HELPER_H_
6#define PRINTING_BACKEND_WIN_HELPER_H_
7
8#include <objidl.h>
9#include <prntvpt.h>
10#include <winspool.h>
11#include <xpsprint.h>
12
13#include <string>
14
15#include "base/memory/scoped_ptr.h"
16#include "base/strings/string16.h"
17#include "base/win/scoped_handle.h"
18#include "printing/printing_export.h"
19
20// These are helper functions for dealing with Windows Printing.
21namespace printing {
22
23struct PRINTING_EXPORT PrinterBasicInfo;
24
25class PrinterHandleTraits {
26 public:
27  typedef HANDLE Handle;
28
29  static bool CloseHandle(HANDLE handle) {
30    return ::ClosePrinter(handle) != FALSE;
31  }
32
33  static bool IsHandleValid(HANDLE handle) {
34    return handle != NULL;
35  }
36
37  static HANDLE NullHandle() {
38    return NULL;
39  }
40
41 private:
42  DISALLOW_IMPLICIT_CONSTRUCTORS(PrinterHandleTraits);
43};
44
45class ScopedPrinterHandle
46    : public base::win::GenericScopedHandle<PrinterHandleTraits,
47                                            base::win::VerifierTraits> {
48 public:
49  bool OpenPrinter(const wchar_t* printer) {
50    HANDLE temp_handle;
51    // ::OpenPrinter may return error but assign some value into handle.
52    if (::OpenPrinter(const_cast<LPTSTR>(printer), &temp_handle, NULL)) {
53      Set(temp_handle);
54    }
55    return IsValid();
56  }
57
58 private:
59  typedef base::win::GenericScopedHandle<PrinterHandleTraits,
60                                         base::win::VerifierTraits> Base;
61};
62
63class PrinterChangeHandleTraits {
64 public:
65  typedef HANDLE Handle;
66
67  static bool CloseHandle(HANDLE handle) {
68    ::FindClosePrinterChangeNotification(handle);
69    return true;
70  }
71
72  static bool IsHandleValid(HANDLE handle) {
73    return handle != NULL;
74  }
75
76  static HANDLE NullHandle() {
77    return NULL;
78  }
79
80 private:
81  DISALLOW_IMPLICIT_CONSTRUCTORS(PrinterChangeHandleTraits);
82};
83
84typedef base::win::GenericScopedHandle<PrinterChangeHandleTraits,
85                                       base::win::DummyVerifierTraits>
86    ScopedPrinterChangeHandle;
87
88// Wrapper class to wrap the XPS APIs (PTxxx APIs). This is needed because these
89// APIs are not available by default on XP. We could delayload prntvpt.dll but
90// this would mean having to add that to every binary that links with
91// printing.lib (which is a LOT of binaries). So choosing the GetProcAddress
92// route instead).
93class PRINTING_EXPORT XPSModule {
94 public:
95  // All the other methods can ONLY be called after a successful call to Init.
96  // Init can be called many times and by multiple threads.
97  static bool Init();
98  static HRESULT OpenProvider(const base::string16& printer_name,
99                              DWORD version,
100                              HPTPROVIDER* provider);
101  static HRESULT GetPrintCapabilities(HPTPROVIDER provider,
102                                      IStream* print_ticket,
103                                      IStream* capabilities,
104                                      BSTR* error_message);
105  static HRESULT ConvertDevModeToPrintTicket(HPTPROVIDER provider,
106                                             ULONG devmode_size_in_bytes,
107                                             PDEVMODE devmode,
108                                             EPrintTicketScope scope,
109                                             IStream* print_ticket);
110  static HRESULT ConvertPrintTicketToDevMode(
111      HPTPROVIDER provider,
112      IStream* print_ticket,
113      EDefaultDevmodeType base_devmode_type,
114      EPrintTicketScope scope,
115      ULONG* devmode_byte_count,
116      PDEVMODE* devmode,
117      BSTR* error_message);
118  static HRESULT MergeAndValidatePrintTicket(HPTPROVIDER provider,
119                                             IStream* base_ticket,
120                                             IStream* delta_ticket,
121                                             EPrintTicketScope scope,
122                                             IStream* result_ticket,
123                                             BSTR* error_message);
124  static HRESULT ReleaseMemory(PVOID buffer);
125  static HRESULT CloseProvider(HPTPROVIDER provider);
126
127 private:
128  XPSModule() { }
129  static bool InitImpl();
130};
131
132// See comments in cc file explaining why we need this.
133class PRINTING_EXPORT ScopedXPSInitializer {
134 public:
135  ScopedXPSInitializer();
136  ~ScopedXPSInitializer();
137
138  bool initialized() const { return initialized_; }
139
140 private:
141  bool initialized_;
142};
143
144// Wrapper class to wrap the XPS Print APIs (these are different from the PTxxx
145// which deal with the XML Print Schema). This is needed because these
146// APIs are only available on Windows 7 and higher.
147class PRINTING_EXPORT XPSPrintModule {
148 public:
149  // All the other methods can ONLY be called after a successful call to Init.
150  // Init can be called many times and by multiple threads.
151  static bool Init();
152  static HRESULT StartXpsPrintJob(
153      const LPCWSTR printer_name,
154      const LPCWSTR job_name,
155      const LPCWSTR output_file_name,
156      HANDLE progress_event,
157      HANDLE completion_event,
158      UINT8* printable_pages_on,
159      UINT32 printable_pages_on_count,
160      IXpsPrintJob **xps_print_job,
161      IXpsPrintJobStream **document_stream,
162      IXpsPrintJobStream **print_ticket_stream);
163 private:
164  XPSPrintModule() { }
165  static bool InitImpl();
166};
167
168PRINTING_EXPORT bool InitBasicPrinterInfo(HANDLE printer,
169                                          PrinterBasicInfo* printer_info);
170
171PRINTING_EXPORT std::string GetDriverInfo(HANDLE printer);
172
173PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode(
174    const base::string16& printer_name,
175    const std::string& print_ticket);
176
177// Creates default DEVMODE and sets color option. Some devices need special
178// workaround for color.
179PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor(
180    HANDLE printer,
181    const base::string16& printer_name,
182    bool color);
183
184// Creates new DEVMODE. If |in| is not NULL copy settings from there.
185PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(
186    HANDLE printer,
187    DEVMODE* in);
188
189}  // namespace printing
190
191#endif  // PRINTING_BACKEND_WIN_HELPER_H_
192