diff options
-rw-r--r-- | chrome/chrome_dll.gypi | 1 | ||||
-rw-r--r-- | chrome/service/cloud_print/print_system_win.cc | 48 | ||||
-rw-r--r-- | printing/backend/print_backend_win.cc | 23 | ||||
-rw-r--r-- | printing/backend/win_helper.cc | 167 | ||||
-rw-r--r-- | printing/backend/win_helper.h | 49 |
5 files changed, 249 insertions, 39 deletions
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 2ee9452..d04b373 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -35,7 +35,6 @@ 'urlmon.dll', 'imm32.dll', 'iphlpapi.dll', - 'prntvpt.dll', ], # Set /SUBSYSTEM:WINDOWS for chrome.dll (for consistency). 'SubSystem': '2', diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc index ea5ede2..62a5b54 100644 --- a/chrome/service/cloud_print/print_system_win.cc +++ b/chrome/service/cloud_print/print_system_win.cc @@ -5,7 +5,6 @@ #include "chrome/service/cloud_print/print_system.h" #include <objidl.h> -#include <prntvpt.h> #include <winspool.h> #include "base/file_path.h" @@ -24,8 +23,6 @@ #include "printing/native_metafile.h" #include "printing/page_range.h" -#pragma comment(lib, "prntvpt.lib") - using base::win::ScopedBstr; using base::win::ScopedComPtr; @@ -85,23 +82,25 @@ HRESULT PrintTicketToDevMode(const std::string& printer_name, return hr; HPTPROVIDER provider = NULL; - hr = PTOpenProvider(UTF8ToWide(printer_name).c_str(), 1, &provider); + hr = printing::XPSModule::OpenProvider(UTF8ToWide(printer_name), + 1, + &provider); if (SUCCEEDED(hr)) { ULONG size = 0; DEVMODE* dm = NULL; - hr = PTConvertPrintTicketToDevMode(provider, - pt_stream, - kUserDefaultDevmode, - kPTDocumentScope, - &size, - &dm, - NULL); + hr = printing::XPSModule::ConvertPrintTicketToDevMode(provider, + pt_stream, + kUserDefaultDevmode, + kPTDocumentScope, + &size, + &dm, + NULL); if (SUCCEEDED(hr)) { dev_mode->Allocate(size); memcpy(dev_mode->dm_, dm, size); - PTReleaseMemory(dm); + printing::XPSModule::ReleaseMemory(dm); } - PTCloseProvider(provider); + printing::XPSModule::CloseProvider(provider); } return hr; } @@ -377,7 +376,7 @@ class PrintSystemWin : public PrintSystem { return false; } - if (!printing::InitXPSModule()) { + if (!printing::XPSModule::Init()) { // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) return false; } @@ -543,13 +542,15 @@ bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) { bool PrintSystemWin::ValidatePrintTicket( const std::string& printer_name, const std::string& print_ticket_data) { - if (!printing::InitXPSModule()) { + if (!printing::XPSModule::Init()) { // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) return false; } bool ret = false; HPTPROVIDER provider = NULL; - PTOpenProvider(UTF8ToWide(printer_name.c_str()).c_str(), 1, &provider); + printing::XPSModule::OpenProvider(UTF8ToWide(printer_name.c_str()), + 1, + &provider); if (provider) { ScopedComPtr<IStream> print_ticket_stream; CreateStreamOnHGlobal(NULL, TRUE, print_ticket_stream.Receive()); @@ -564,13 +565,14 @@ bool PrintSystemWin::ValidatePrintTicket( ScopedBstr error; ScopedComPtr<IStream> result_ticket_stream; CreateStreamOnHGlobal(NULL, TRUE, result_ticket_stream.Receive()); - ret = SUCCEEDED(PTMergeAndValidatePrintTicket(provider, - print_ticket_stream.get(), - NULL, - kPTJobScope, - result_ticket_stream.get(), - error.Receive())); - PTCloseProvider(provider); + ret = SUCCEEDED(printing::XPSModule::MergeAndValidatePrintTicket( + provider, + print_ticket_stream.get(), + NULL, + kPTJobScope, + result_ticket_stream.get(), + error.Receive())); + printing::XPSModule::CloseProvider(provider); } return ret; } diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc index 4cfd400..909904b 100644 --- a/printing/backend/print_backend_win.cc +++ b/printing/backend/print_backend_win.cc @@ -5,7 +5,6 @@ #include "printing/backend/print_backend.h" #include <objidl.h> -#include <prntvpt.h> #include <winspool.h> #include "base/scoped_ptr.h" @@ -17,8 +16,6 @@ #include "printing/backend/print_backend_consts.h" #include "printing/backend/win_helper.h" -#pragma comment(lib, "prntvpt.lib") - using base::win::ScopedBstr; using base::win::ScopedComPtr; using base::win::ScopedHGlobal; @@ -89,7 +86,7 @@ void PrintBackendWin::EnumeratePrinters(PrinterList* printer_list) { bool PrintBackendWin::GetPrinterCapsAndDefaults( const std::string& printer_name, PrinterCapsAndDefaults* printer_info) { - if (!printing::InitXPSModule()) { + if (!XPSModule::Init()) { // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) return false; } @@ -99,7 +96,7 @@ bool PrintBackendWin::GetPrinterCapsAndDefaults( DCHECK(printer_info); HPTPROVIDER provider = NULL; std::wstring printer_name_wide = UTF8ToWide(printer_name); - HRESULT hr = PTOpenProvider(printer_name_wide.c_str(), 1, &provider); + HRESULT hr = XPSModule::OpenProvider(printer_name_wide, 1, &provider); DCHECK(SUCCEEDED(hr)); if (provider) { ScopedComPtr<IStream> print_capabilities_stream; @@ -108,8 +105,10 @@ bool PrintBackendWin::GetPrinterCapsAndDefaults( DCHECK(SUCCEEDED(hr)); if (print_capabilities_stream) { ScopedBstr error; - hr = PTGetPrintCapabilities(provider, NULL, print_capabilities_stream, - error.Receive()); + hr = XPSModule::GetPrintCapabilities(provider, + NULL, + print_capabilities_stream, + error.Receive()); DCHECK(SUCCEEDED(hr)); if (FAILED(hr)) { return false; @@ -140,9 +139,11 @@ bool PrintBackendWin::GetPrinterCapsAndDefaults( printer_defaults_stream.Receive()); DCHECK(SUCCEEDED(hr)); if (printer_defaults_stream) { - hr = PTConvertDevModeToPrintTicket(provider, devmode_size, - devmode_out, kPTJobScope, - printer_defaults_stream); + hr = XPSModule::ConvertDevModeToPrintTicket(provider, + devmode_size, + devmode_out, + kPTJobScope, + printer_defaults_stream); DCHECK(SUCCEEDED(hr)); if (SUCCEEDED(hr)) { hr = StreamOnHGlobalToString(printer_defaults_stream.get(), @@ -153,7 +154,7 @@ bool PrintBackendWin::GetPrinterCapsAndDefaults( } ClosePrinter(printer_handle); } - PTCloseProvider(provider); + XPSModule::CloseProvider(provider); } return true; } diff --git a/printing/backend/win_helper.cc b/printing/backend/win_helper.cc index a5f515f..72f2528 100644 --- a/printing/backend/win_helper.cc +++ b/printing/backend/win_helper.cc @@ -4,14 +4,175 @@ #include "printing/backend/win_helper.h" +#include "base/logging.h" -#include <windows.h> +namespace { +typedef HRESULT (WINAPI *PTOpenProviderProc)(PCWSTR printer_name, + DWORD version, + HPTPROVIDER *provider); +typedef HRESULT (WINAPI *PTGetPrintCapabilitiesProc)(HPTPROVIDER provider, + IStream *print_ticket, + IStream *capabilities, + BSTR* error_message); +typedef HRESULT (WINAPI *PTConvertDevModeToPrintTicketProc)( + HPTPROVIDER provider, + ULONG devmode_size_in_bytes, + PDEVMODE devmode, + EPrintTicketScope scope, + IStream* print_ticket); +typedef HRESULT (WINAPI *PTConvertPrintTicketToDevModeProc)( + HPTPROVIDER provider, + IStream* print_ticket, + EDefaultDevmodeType base_devmode_type, + EPrintTicketScope scope, + ULONG* devmode_byte_count, + PDEVMODE *devmode, + BSTR* error_message); +typedef HRESULT (WINAPI *PTMergeAndValidatePrintTicketProc)( + HPTPROVIDER provider, + IStream* base_ticket, + IStream* delta_ticket, + EPrintTicketScope scope, + IStream* result_ticket, + BSTR* error_message); +typedef HRESULT (WINAPI *PTReleaseMemoryProc)(PVOID buffer); +typedef HRESULT (WINAPI *PTCloseProviderProc)(HPTPROVIDER provider); + +PTOpenProviderProc g_open_provider_proc = NULL; +PTGetPrintCapabilitiesProc g_get_print_capabilities_proc = NULL; +PTConvertDevModeToPrintTicketProc g_convert_devmode_to_print_ticket_proc = NULL; +PTConvertPrintTicketToDevModeProc g_convert_print_ticket_to_devmode_proc = NULL; +PTMergeAndValidatePrintTicketProc g_merge_and_validate_print_ticket_proc = NULL; +PTReleaseMemoryProc g_release_memory_proc = NULL; +PTCloseProviderProc g_close_provider_proc = NULL; +} namespace printing { -bool InitXPSModule() { +bool XPSModule::Init() { + static bool initialized = InitImpl(); + return initialized; +} + +bool XPSModule::InitImpl() { HMODULE prntvpt_module = LoadLibrary(L"prntvpt.dll"); - return (NULL != prntvpt_module); + if (prntvpt_module == NULL) + return false; + g_open_provider_proc = reinterpret_cast<PTOpenProviderProc>( + GetProcAddress(prntvpt_module, "PTOpenProvider")); + if (!g_open_provider_proc) { + NOTREACHED(); + return false; + } + g_get_print_capabilities_proc = reinterpret_cast<PTGetPrintCapabilitiesProc>( + GetProcAddress(prntvpt_module, "PTGetPrintCapabilities")); + if (!g_get_print_capabilities_proc) { + NOTREACHED(); + return false; + } + g_convert_devmode_to_print_ticket_proc = + reinterpret_cast<PTConvertDevModeToPrintTicketProc>( + GetProcAddress(prntvpt_module, "PTConvertDevModeToPrintTicket")); + if (!g_convert_devmode_to_print_ticket_proc) { + NOTREACHED(); + return false; + } + g_convert_print_ticket_to_devmode_proc = + reinterpret_cast<PTConvertPrintTicketToDevModeProc>( + GetProcAddress(prntvpt_module, "PTConvertPrintTicketToDevMode")); + if (!g_convert_print_ticket_to_devmode_proc) { + NOTREACHED(); + return false; + } + g_merge_and_validate_print_ticket_proc = + reinterpret_cast<PTMergeAndValidatePrintTicketProc>( + GetProcAddress(prntvpt_module, "PTMergeAndValidatePrintTicket")); + if (!g_merge_and_validate_print_ticket_proc) { + NOTREACHED(); + return false; + } + g_release_memory_proc = + reinterpret_cast<PTReleaseMemoryProc>( + GetProcAddress(prntvpt_module, "PTReleaseMemory")); + if (!g_release_memory_proc) { + NOTREACHED(); + return false; + } + g_close_provider_proc = + reinterpret_cast<PTCloseProviderProc>( + GetProcAddress(prntvpt_module, "PTCloseProvider")); + if (!g_close_provider_proc) { + NOTREACHED(); + return false; + } + return true; +} + +HRESULT XPSModule::OpenProvider(const string16& printer_name, + DWORD version, + HPTPROVIDER *provider) { + return g_open_provider_proc(printer_name.c_str(), version, provider); +} + +HRESULT XPSModule::GetPrintCapabilities(HPTPROVIDER provider, + IStream *print_ticket, + IStream *capabilities, + BSTR* error_message) { + return g_get_print_capabilities_proc(provider, + print_ticket, + capabilities, + error_message); +} + +HRESULT XPSModule::ConvertDevModeToPrintTicket(HPTPROVIDER provider, + ULONG devmode_size_in_bytes, + PDEVMODE devmode, + EPrintTicketScope scope, + IStream* print_ticket) { + return g_convert_devmode_to_print_ticket_proc(provider, + devmode_size_in_bytes, + devmode, + scope, + print_ticket); +} + +HRESULT XPSModule::ConvertPrintTicketToDevMode( + HPTPROVIDER provider, + IStream* print_ticket, + EDefaultDevmodeType base_devmode_type, + EPrintTicketScope scope, + ULONG* devmode_byte_count, + PDEVMODE *devmode, + BSTR* error_message) { + return g_convert_print_ticket_to_devmode_proc(provider, + print_ticket, + base_devmode_type, + scope, + devmode_byte_count, + devmode, + error_message); +} + +HRESULT XPSModule::MergeAndValidatePrintTicket(HPTPROVIDER provider, + IStream* base_ticket, + IStream* delta_ticket, + EPrintTicketScope scope, + IStream* result_ticket, + BSTR* error_message) { + return g_merge_and_validate_print_ticket_proc(provider, + base_ticket, + delta_ticket, + scope, + result_ticket, + error_message); +} + +HRESULT XPSModule::ReleaseMemory(PVOID buffer) { + return g_release_memory_proc(buffer); +} + +HRESULT XPSModule::CloseProvider(HPTPROVIDER provider) { + return g_close_provider_proc(provider); } } // namespace printing diff --git a/printing/backend/win_helper.h b/printing/backend/win_helper.h index a779ad7..8b99a35 100644 --- a/printing/backend/win_helper.h +++ b/printing/backend/win_helper.h @@ -6,10 +6,57 @@ #define PRINTING_BACKEND_WIN_HELPER_H_ #pragma once +#include <objidl.h> +#include <winspool.h> +#include <prntvpt.h> + +#include "base/string16.h" + // These are helper functions for dealing with Windows Printing. namespace printing { -bool InitXPSModule(); +// 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 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 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(); +}; } // namespace printing |