summaryrefslogtreecommitdiffstats
path: root/printing/backend/win_helper.h
blob: fa39a0367f7bfc4fbe92a9de88867ff69d82e283 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PRINTING_BACKEND_WIN_HELPER_H_
#define PRINTING_BACKEND_WIN_HELPER_H_

#include <objidl.h>
#include <prntvpt.h>
#include <winspool.h>
#include <xpsprint.h>

#include <string>

#include "base/macros.h"
#include "base/memory/free_deleter.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/win/scoped_handle.h"
#include "printing/printing_export.h"

// These are helper functions for dealing with Windows Printing.
namespace printing {

struct PRINTING_EXPORT PrinterBasicInfo;

class PrinterHandleTraits {
 public:
  typedef HANDLE Handle;

  static bool CloseHandle(HANDLE handle) {
    return ::ClosePrinter(handle) != FALSE;
  }

  static bool IsHandleValid(HANDLE handle) {
    return handle != NULL;
  }

  static HANDLE NullHandle() {
    return NULL;
  }

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(PrinterHandleTraits);
};

class ScopedPrinterHandle
    : public base::win::GenericScopedHandle<PrinterHandleTraits,
                                            base::win::DummyVerifierTraits> {
 public:
  bool OpenPrinter(const wchar_t* printer) {
    HANDLE temp_handle;
    // ::OpenPrinter may return error but assign some value into handle.
    if (::OpenPrinter(const_cast<LPTSTR>(printer), &temp_handle, NULL)) {
      Set(temp_handle);
    }
    return IsValid();
  }

 private:
  typedef base::win::GenericScopedHandle<PrinterHandleTraits,
                                         base::win::DummyVerifierTraits> Base;
};

class PrinterChangeHandleTraits {
 public:
  typedef HANDLE Handle;

  static bool CloseHandle(HANDLE handle) {
    ::FindClosePrinterChangeNotification(handle);
    return true;
  }

  static bool IsHandleValid(HANDLE handle) {
    return handle != NULL;
  }

  static HANDLE NullHandle() {
    return NULL;
  }

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(PrinterChangeHandleTraits);
};

typedef base::win::GenericScopedHandle<PrinterChangeHandleTraits,
                                       base::win::DummyVerifierTraits>
    ScopedPrinterChangeHandle;

// Wrapper class to wrap the XPS APIs (PTxxx APIs). This is needed because these
// APIs are not available by default on XP. We could delayload prntvpt.dll but
// this would mean having to add that to every binary that links with
// printing.lib (which is a LOT of binaries). So choosing the GetProcAddress
// route instead).
class PRINTING_EXPORT XPSModule {
 public:
  // All the other methods can ONLY be called after a successful call to Init.
  // Init can be called many times and by multiple threads.
  static bool Init();
  static HRESULT OpenProvider(const base::string16& printer_name,
                              DWORD version,
                              HPTPROVIDER* provider);
  static HRESULT GetPrintCapabilities(HPTPROVIDER provider,
                                      IStream* print_ticket,
                                      IStream* capabilities,
                                      BSTR* error_message);
  static HRESULT ConvertDevModeToPrintTicket(HPTPROVIDER provider,
                                             ULONG devmode_size_in_bytes,
                                             PDEVMODE devmode,
                                             EPrintTicketScope scope,
                                             IStream* print_ticket);
  static HRESULT ConvertPrintTicketToDevMode(
      HPTPROVIDER provider,
      IStream* print_ticket,
      EDefaultDevmodeType base_devmode_type,
      EPrintTicketScope scope,
      ULONG* devmode_byte_count,
      PDEVMODE* devmode,
      BSTR* error_message);
  static HRESULT MergeAndValidatePrintTicket(HPTPROVIDER provider,
                                             IStream* base_ticket,
                                             IStream* delta_ticket,
                                             EPrintTicketScope scope,
                                             IStream* result_ticket,
                                             BSTR* error_message);
  static HRESULT ReleaseMemory(PVOID buffer);
  static HRESULT CloseProvider(HPTPROVIDER provider);

 private:
  XPSModule() { }
  static bool InitImpl();
};

// See comments in cc file explaining why we need this.
class PRINTING_EXPORT ScopedXPSInitializer {
 public:
  ScopedXPSInitializer();
  ~ScopedXPSInitializer();

  bool initialized() const { return initialized_; }

 private:
  bool initialized_;
};

// Wrapper class to wrap the XPS Print APIs (these are different from the PTxxx
// which deal with the XML Print Schema). This is needed because these
// APIs are only available on Windows 7 and higher.
class PRINTING_EXPORT XPSPrintModule {
 public:
  // All the other methods can ONLY be called after a successful call to Init.
  // Init can be called many times and by multiple threads.
  static bool Init();
  static HRESULT StartXpsPrintJob(
      const LPCWSTR printer_name,
      const LPCWSTR job_name,
      const LPCWSTR output_file_name,
      HANDLE progress_event,
      HANDLE completion_event,
      UINT8* printable_pages_on,
      UINT32 printable_pages_on_count,
      IXpsPrintJob **xps_print_job,
      IXpsPrintJobStream **document_stream,
      IXpsPrintJobStream **print_ticket_stream);
 private:
  XPSPrintModule() { }
  static bool InitImpl();
};

PRINTING_EXPORT bool InitBasicPrinterInfo(HANDLE printer,
                                          PrinterBasicInfo* printer_info);

PRINTING_EXPORT std::string GetDriverInfo(HANDLE printer);

PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode(
    const base::string16& printer_name,
    const std::string& print_ticket);

// Creates default DEVMODE and sets color option. Some devices need special
// workaround for color.
PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor(
    HANDLE printer,
    const base::string16& printer_name,
    bool color);

// Creates new DEVMODE. If |in| is not NULL copy settings from there.
PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(
    HANDLE printer,
    DEVMODE* in);

// Prompts for new DEVMODE. If |in| is not NULL copy settings from there.
PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode(
    HANDLE printer,
    const base::string16& printer_name,
    DEVMODE* in,
    HWND window,
    bool* canceled);

}  // namespace printing

#endif  // PRINTING_BACKEND_WIN_HELPER_H_