| 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) {
|
|
|