Index: printing/backend/win_helper.cc |
diff --git a/printing/backend/win_helper.cc b/printing/backend/win_helper.cc |
index c96e123c7d2aeab023c9d0f07b478b851004340c..99d0e6f9360a7059cc30c21860fa287853a5768d 100644 |
--- a/printing/backend/win_helper.cc |
+++ b/printing/backend/win_helper.cc |
@@ -19,6 +19,7 @@ |
#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/win/scoped_comptr.h" |
+#include "base/win/windows_version.h" |
#include "printing/backend/print_backend.h" |
#include "printing/backend/print_backend_consts.h" |
#include "printing/backend/printing_info_win.h" |
@@ -470,6 +471,22 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( |
return ticket; |
} |
+bool IsPrinterRPCSOnly(HANDLE printer) { |
+ PrinterInfo5 info_5; |
+ if (!info_5.Init(printer)) |
+ return false; |
+ const wchar_t* name = info_5.get()->pPrinterName; |
+ const wchar_t* port = info_5.get()->pPortName; |
+ int num_languages = |
+ DeviceCapabilities(name, port, DC_PERSONALITY, NULL, NULL); |
+ if (num_languages != 1) |
+ return false; |
+ std::vector<wchar_t> buf(33, 0); |
+ DeviceCapabilities(name, port, DC_PERSONALITY, buf.data(), NULL); |
+ static constexpr wchar_t kRPCSLanguage[] = L"RPCS"; |
+ return wcscmp(buf.data(), kRPCSLanguage) == 0; |
+} |
+ |
std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, |
DEVMODE* in) { |
LONG buffer_size = DocumentProperties( |
@@ -484,6 +501,14 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, |
std::unique_ptr<DEVMODE, base::FreeDeleter> out( |
reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); |
DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; |
+ |
+ // Check for RPCS drivers on Windows 8+ as DocumentProperties will crash if |
+ // called on one of these printers. See crbug.com/679160 |
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8 && |
+ IsPrinterRPCSOnly(printer)) { |
+ return std::unique_ptr<DEVMODE, base::FreeDeleter>(); |
+ } |
+ |
if (DocumentProperties( |
NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != |
IDOK) { |