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