From 4ca43c71eb4f1b2cb969a219e3f1d3b12af02309 Mon Sep 17 00:00:00 2001 From: Mike Kuta Date: Fri, 6 Feb 2015 11:34:28 -0500 Subject: Improved Windows printer support and fixed crashes due to NULL devMode With certain printer drivers, the PRINTER_INFO_2 can return NULL for the pDevMode member in the call to GetPrinter() as mentioned on MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd144911 In many places, Qt first checks that devMode isn't NULL before dereferencing it. In other places it does not (such as when it actually attempts to print in QWin32PrintEngine::begin()). Checking every dereference aside, most printer functionality is removed without access to the DEVMODE structure. This fix uses DocumentProperties() to get the DEVMODE information when the first method fails. [ChangeLog][QtPrintSupport][QPrinter][Windows] Improved Windows printer support and fixed crashes due to NULL devMode Task-number: QTBUG-44349 Task-number: QTBUG-43877 Task-number: QTBUG-2251 Change-Id: Iafa337055d967c70f2096dcde4cc9c8ca8a0d252 Reviewed-by: Andy Shaw --- .../printsupport/windows/qwindowsprintdevice.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/plugins/printsupport/windows/qwindowsprintdevice.cpp') diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index c349655b1e..31c47f9660 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -248,8 +248,20 @@ QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize, if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) { PPRINTER_INFO_2 info = reinterpret_cast(buffer.data()); DEVMODE *devMode = info->pDevMode; - if (!devMode) - return margins; + bool separateDevMode = false; + if (!devMode) { + // GetPrinter() didn't include the DEVMODE. Get it a different way. + LONG result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), + NULL, NULL, 0); + devMode = (DEVMODE *)malloc(result); + separateDevMode = true; + result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), + devMode, NULL, DM_OUT_BUFFER); + if (result != IDOK) { + free(devMode); + return margins; + } + } HDC pDC = CreateDC(NULL, (LPWSTR)m_id.utf16(), NULL, devMode); if (pageSize.id() == QPageSize::Custom || pageSize.windowsId() <= 0 || pageSize.windowsId() > DMPAPER_LAST) { @@ -275,6 +287,8 @@ QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize, const qreal rightMargin = physicalWidth - leftMargin - printableWidth; const qreal bottomMargin = physicalHeight - topMargin - printableHeight; margins = QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin); + if (separateDevMode) + free(devMode); DeleteDC(pDC); } return margins; -- cgit v1.2.3