OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "printing/backend/print_backend.h" | 5 #include "printing/backend/print_backend.h" |
6 | 6 |
7 #include <objidl.h> | 7 #include <objidl.h> |
8 #include <winspool.h> | 8 #include <winspool.h> |
9 | 9 |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/string_piece.h" | 11 #include "base/string_piece.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "base/win/scoped_bstr.h" | 13 #include "base/win/scoped_bstr.h" |
14 #include "base/win/scoped_comptr.h" | 14 #include "base/win/scoped_comptr.h" |
15 #include "base/win/scoped_hglobal.h" | 15 #include "base/win/scoped_hglobal.h" |
16 #include "printing/backend/print_backend_consts.h" | 16 #include "printing/backend/print_backend_consts.h" |
| 17 #include "printing/backend/printing_info_win.h" |
17 #include "printing/backend/win_helper.h" | 18 #include "printing/backend/win_helper.h" |
18 | 19 |
| 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 // This class is designed to work with PRINTER_INFO_X structures | |
22 // and calls GetPrinter internally with correctly allocated buffer. | |
23 template <typename T> | |
24 class PrinterInfo { | |
25 public: | |
26 bool GetPrinterInfo(HANDLE printer, int level) { | |
27 DWORD buf_size = 0; | |
28 GetPrinter(printer, level, NULL, 0, &buf_size); | |
29 if (buf_size == 0) { | |
30 LOG(WARNING) << "Failed to GetPrinter, error = " << GetLastError(); | |
31 return false; | |
32 } | |
33 buffer_.reset(new uint8[buf_size]); | |
34 memset(buffer_.get(), 0, buf_size); | |
35 return !!GetPrinter(printer, level, buffer_.get(), buf_size, &buf_size); | |
36 } | |
37 | |
38 const T* get() const { | |
39 return reinterpret_cast<T*>(buffer_.get()); | |
40 } | |
41 | |
42 private: | |
43 scoped_array<uint8> buffer_; | |
44 }; | |
45 | |
46 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { | 23 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { |
47 DCHECK(stream); | 24 DCHECK(stream); |
48 DCHECK(out); | 25 DCHECK(out); |
49 HGLOBAL hdata = NULL; | 26 HGLOBAL hdata = NULL; |
50 HRESULT hr = GetHGlobalFromStream(stream, &hdata); | 27 HRESULT hr = GetHGlobalFromStream(stream, &hdata); |
51 if (SUCCEEDED(hr)) { | 28 if (SUCCEEDED(hr)) { |
52 DCHECK(hdata); | 29 DCHECK(hdata); |
53 base::win::ScopedHGlobal<char> locked_data(hdata); | 30 base::win::ScopedHGlobal<char> locked_data(hdata); |
54 out->assign(locked_data.release(), locked_data.Size()); | 31 out->assign(locked_data.release(), locked_data.Size()); |
55 } | 32 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 PrinterSemanticCapsAndDefaults* printer_info) { | 103 PrinterSemanticCapsAndDefaults* printer_info) { |
127 ScopedPrinterHandle printer_handle; | 104 ScopedPrinterHandle printer_handle; |
128 OpenPrinter(const_cast<LPTSTR>(UTF8ToWide(printer_name).c_str()), | 105 OpenPrinter(const_cast<LPTSTR>(UTF8ToWide(printer_name).c_str()), |
129 printer_handle.Receive(), NULL); | 106 printer_handle.Receive(), NULL); |
130 DCHECK(printer_handle); | 107 DCHECK(printer_handle); |
131 if (!printer_handle.IsValid()) { | 108 if (!printer_handle.IsValid()) { |
132 LOG(WARNING) << "Failed to open printer, error = " << GetLastError(); | 109 LOG(WARNING) << "Failed to open printer, error = " << GetLastError(); |
133 return false; | 110 return false; |
134 } | 111 } |
135 | 112 |
136 PrinterInfo<PRINTER_INFO_5> info_5; | 113 PrinterInfo5 info_5; |
137 if (!info_5.GetPrinterInfo(printer_handle, 5)) { | 114 if (!info_5.Init(printer_handle)) { |
138 LOG(WARNING) << "Failed to get PRINTER_INFO_5, error = " << GetLastError(); | |
139 return false; | 115 return false; |
140 } | 116 } |
| 117 DCHECK_EQ(info_5.get()->pPrinterName, UTF8ToUTF16(printer_name)); |
| 118 |
| 119 PrinterSemanticCapsAndDefaults caps; |
141 | 120 |
142 // Get printer capabilities. For more info see here: | 121 // Get printer capabilities. For more info see here: |
143 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a
spx | 122 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a
spx |
144 bool color_supported = (DeviceCapabilities(info_5.get()->pPrinterName, | 123 caps.color_capable = (::DeviceCapabilities(info_5.get()->pPrinterName, |
145 info_5.get()->pPortName, | 124 info_5.get()->pPortName, |
146 DC_COLORDEVICE, | 125 DC_COLORDEVICE, |
147 NULL, | 126 NULL, |
148 NULL) == 1); | 127 NULL) == 1); |
149 | 128 |
150 bool duplex_supported = (DeviceCapabilities(info_5.get()->pPrinterName, | 129 caps.duplex_capable = (::DeviceCapabilities(info_5.get()->pPrinterName, |
151 info_5.get()->pPortName, | 130 info_5.get()->pPortName, |
152 DC_DUPLEX, | 131 DC_DUPLEX, |
153 NULL, | 132 NULL, |
154 NULL) == 1); | 133 NULL) == 1); |
155 | 134 |
156 DEVMODE* devmode = NULL; | 135 UserDefaultDevMode user_settings; |
157 // Retrieves user defaults. | |
158 PrinterInfo<PRINTER_INFO_9> info_9; | |
159 if (info_9.GetPrinterInfo(printer_handle, 9)) { | |
160 devmode = info_9.get()->pDevMode; | |
161 } else { | |
162 LOG(WARNING) << "Failed to get PRINTER_INFO_9, error = " << GetLastError(); | |
163 } | |
164 | 136 |
165 // Retrieves admin defaults. | 137 if (user_settings.Init(printer_handle)) { |
166 PrinterInfo<PRINTER_INFO_8> info_8; | 138 if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR) |
167 if (!devmode) { | 139 caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR); |
168 if (info_8.GetPrinterInfo(printer_handle, 8)) { | |
169 devmode = info_8.get()->pDevMode; | |
170 } else { | |
171 LOG(WARNING) << "Failed to get PRINTER_INFO_8, error = " << | |
172 GetLastError(); | |
173 } | |
174 } | |
175 | 140 |
176 // Retrieves printer defaults. | 141 if ((user_settings.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) { |
177 PrinterInfo<PRINTER_INFO_2> info_2; | 142 switch (user_settings.get()->dmDuplex) { |
178 if (!devmode) { | 143 case DMDUP_SIMPLEX: |
179 if (info_2.GetPrinterInfo(printer_handle, 2)) { | 144 caps.duplex_default = SIMPLEX; |
180 devmode = info_2.get()->pDevMode; | 145 break; |
181 } else { | 146 case DMDUP_VERTICAL: |
182 LOG(WARNING) << "Failed to get PRINTER_INFO_2, error = " << | 147 caps.duplex_default = LONG_EDGE; |
183 GetLastError(); | 148 break; |
184 } | 149 case DMDUP_HORIZONTAL: |
185 } | 150 caps.duplex_default = SHORT_EDGE; |
186 | 151 break; |
187 PrinterSemanticCapsAndDefaults caps; | 152 default: |
188 caps.color_capable = color_supported; | 153 NOTREACHED(); |
189 caps.duplex_capable = duplex_supported; | |
190 | |
191 if (devmode) { | |
192 if ((devmode->dmFields & DM_COLOR) == DM_COLOR) | |
193 caps.color_default = (devmode->dmColor == DMCOLOR_COLOR); | |
194 if ((devmode->dmFields & DM_DUPLEX) == DM_DUPLEX) { | |
195 switch (devmode->dmDuplex) { | |
196 case DMDUP_SIMPLEX: | |
197 caps.duplex_default = SIMPLEX; | |
198 break; | |
199 case DMDUP_VERTICAL: | |
200 caps.duplex_default = LONG_EDGE; | |
201 break; | |
202 case DMDUP_HORIZONTAL: | |
203 caps.duplex_default = SHORT_EDGE; | |
204 break; | |
205 default: | |
206 NOTREACHED(); | |
207 } | 154 } |
208 } | 155 } |
209 } else { | 156 } else { |
210 LOG(WARNING) << "Fallback to color/simplex mode."; | 157 LOG(WARNING) << "Fallback to color/simplex mode."; |
211 caps.color_default = caps.color_capable; | 158 caps.color_default = caps.color_capable; |
212 caps.duplex_default = SIMPLEX; | 159 caps.duplex_default = SIMPLEX; |
213 } | 160 } |
214 | 161 |
215 *printer_info = caps; | 162 *printer_info = caps; |
216 return true; | 163 return true; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 printer_handle.Receive(), NULL); | 255 printer_handle.Receive(), NULL); |
309 return printer_handle.IsValid(); | 256 return printer_handle.IsValid(); |
310 } | 257 } |
311 | 258 |
312 scoped_refptr<PrintBackend> PrintBackend::CreateInstance( | 259 scoped_refptr<PrintBackend> PrintBackend::CreateInstance( |
313 const base::DictionaryValue* print_backend_settings) { | 260 const base::DictionaryValue* print_backend_settings) { |
314 return new PrintBackendWin; | 261 return new PrintBackendWin; |
315 } | 262 } |
316 | 263 |
317 } // namespace printing | 264 } // namespace printing |
OLD | NEW |