From 84b6b5faf72790af0e4fb87b28cb517174646a9d Mon Sep 17 00:00:00 2001 From: Doug Lyons Date: Wed, 12 Feb 2020 23:18:57 -0600 Subject: [PATCH 1/4] Implement DocumentPropertiesA --- win32ss/printing/base/winspool/printers.c | 161 +++++++++++++++++++++- 1 file changed, 159 insertions(+), 2 deletions(-) diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index f6616068442..3b37e06c5d4 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -205,9 +205,166 @@ DocumentEvent( HANDLE hPrinter, HDC hdc, int iEsc, ULONG cbIn, PVOID pvIn, ULONG LONG WINAPI DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput, DWORD fMode) { + PWSTR pwszDeviceName = NULL; + PDEVMODEW pdmwInput = NULL; + PDEVMODEW pdmwOutput = NULL; + BOOL bReturnValue = -1; + DWORD cch; + TRACE("DocumentPropertiesA(%p, %p, %s, %p, %p, %lu)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput, fMode); - UNIMPLEMENTED; - return -1; + + if (pDeviceName) + { + // Convert pName to a Unicode string pwszDeviceName. + cch = strlen(pDeviceName); + + pwszDeviceName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); + if (!pwszDeviceName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + MultiByteToWideChar(CP_ACP, 0, pDeviceName, -1, pwszDeviceName, cch + 1); + } + + if (pDevModeInput) + { + // Create working buffer for input to DocumentPropertiesW. + pdmwInput = HeapAlloc(hProcessHeap, 0, sizeof(DEVMODEW)); + if (!pdmwInput) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmDeviceName, -1, pdmwInput->dmDeviceName, CCHDEVICENAME); + pdmwInput->dmSpecVersion = pDevModeInput->dmSpecVersion; + pdmwInput->dmDriverVersion = pDevModeInput->dmDriverVersion; + pdmwInput->dmSize = pDevModeInput->dmSize; + pdmwInput->dmDriverExtra = pDevModeInput->dmDriverExtra; + pdmwInput->dmFields = pDevModeInput->dmFields; + pdmwInput->dmOrientation = pDevModeInput->dmOrientation; + pdmwInput->dmPaperSize = pDevModeInput->dmPaperSize; + pdmwInput->dmPaperLength = pDevModeInput->dmPaperLength; + pdmwInput->dmPaperWidth = pDevModeInput->dmPaperWidth; + pdmwInput->dmScale = pDevModeInput->dmScale; + pdmwInput->dmCopies = pDevModeInput->dmCopies; + pdmwInput->dmDefaultSource = pDevModeInput->dmDefaultSource; + pdmwInput->dmPrintQuality = pDevModeInput->dmPrintQuality; + pdmwInput->dmPosition = pDevModeInput->dmPosition; + pdmwInput->dmDisplayOrientation = pDevModeInput->dmDisplayOrientation; + pdmwInput->dmDisplayFixedOutput = pDevModeInput->dmDisplayFixedOutput; + pdmwInput->dmColor = pDevModeInput->dmColor; + pdmwInput->dmDuplex = pDevModeInput->dmDuplex; + pdmwInput->dmYResolution = pDevModeInput->dmYResolution; + pdmwInput->dmTTOption = pDevModeInput->dmTTOption; + pdmwInput->dmCollate = pDevModeInput->dmCollate; + + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmFormName, -1, pdmwInput->dmFormName, CCHFORMNAME); + + pdmwInput->dmLogPixels = pDevModeInput->dmLogPixels; + pdmwInput->dmBitsPerPel = pDevModeInput->dmBitsPerPel; + pdmwInput->dmPelsWidth = pDevModeInput->dmPelsWidth; + pdmwInput->dmPelsHeight = pDevModeInput->dmPelsHeight; + pdmwInput->dmDisplayFlags = pDevModeInput->dmDisplayFlags; + pdmwInput->dmNup = pDevModeInput->dmNup; + pdmwInput->dmDisplayFrequency = pDevModeInput->dmDisplayFrequency; + pdmwInput->dmICMMethod = pDevModeInput->dmICMMethod; + pdmwInput->dmICMIntent = pDevModeInput->dmICMIntent; + pdmwInput->dmMediaType = pDevModeInput->dmMediaType; + pdmwInput->dmDitherType = pDevModeInput->dmDitherType; + pdmwInput->dmReserved1 = pDevModeInput->dmReserved1; + pdmwInput->dmReserved2 = pDevModeInput->dmReserved2; + pdmwInput->dmPanningWidth = pDevModeInput->dmPanningWidth; + pdmwInput->dmPanningHeight = pDevModeInput->dmPanningHeight; + } + + if (pDevModeOutput) + { + // Create working buffer for output from DocumentPropertiesW. + pdmwOutput = HeapAlloc(hProcessHeap, 0, sizeof(DEVMODEW)); + if (!pdmwOutput) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + } + + bReturnValue = DocumentPropertiesW(hWnd, hPrinter, pwszDeviceName, pdmwOutput, pdmwInput, fMode); + TRACE("bReturnValue from DocumentPropertiesW is '%ld'.\n", bReturnValue); + + if (pwszDeviceName) + { + HeapFree(hProcessHeap, 0, pwszDeviceName); + } + + if (bReturnValue < 0) + { + TRACE("DocumentPropertiesW failed!\n"); + goto Cleanup; + } + + if (pdmwOutput) + { + WideCharToMultiByte(CP_ACP, 0, pdmwOutput->dmDeviceName, -1, (LPSTR)pDevModeOutput->dmDeviceName, CCHDEVICENAME, NULL, NULL); + + pDevModeOutput->dmSpecVersion = pdmwOutput->dmSpecVersion; + pDevModeOutput->dmDriverVersion = pdmwOutput->dmDriverVersion; + pDevModeOutput->dmSize = pdmwOutput->dmSize; + pDevModeOutput->dmDriverExtra = pdmwOutput->dmDriverExtra; + pDevModeOutput->dmFields = pdmwOutput->dmFields; + pDevModeOutput->dmOrientation = pdmwOutput->dmOrientation; + pDevModeOutput->dmPaperSize = pdmwOutput->dmPaperSize; + pDevModeOutput->dmPaperLength = pdmwOutput->dmPaperLength; + pDevModeOutput->dmPaperWidth = pdmwOutput->dmPaperWidth; + pDevModeOutput->dmScale = pdmwOutput->dmScale; + pDevModeOutput->dmCopies = pdmwOutput->dmCopies; + pDevModeOutput->dmDefaultSource = pdmwOutput->dmDefaultSource; + pDevModeOutput->dmPrintQuality = pdmwOutput->dmPrintQuality; + pDevModeOutput->dmPosition = pdmwOutput->dmPosition; + pDevModeOutput->dmDisplayOrientation = pdmwOutput->dmDisplayOrientation; + pDevModeOutput->dmDisplayFixedOutput = pdmwOutput->dmDisplayFixedOutput; + pDevModeOutput->dmColor = pdmwOutput->dmColor; + pDevModeOutput->dmDuplex = pdmwOutput->dmDuplex; + pDevModeOutput->dmYResolution = pdmwOutput->dmYResolution; + pDevModeOutput->dmTTOption = pdmwOutput->dmTTOption; + pDevModeOutput->dmCollate = pdmwOutput->dmCollate; + + WideCharToMultiByte(CP_ACP, 0, pdmwOutput->dmFormName, -1, (LPSTR)pDevModeOutput->dmFormName, CCHFORMNAME, NULL, NULL); + + pDevModeOutput->dmLogPixels = pdmwOutput->dmLogPixels; + pDevModeOutput->dmBitsPerPel = pdmwOutput->dmBitsPerPel; + pDevModeOutput->dmPelsWidth = pdmwOutput->dmPelsWidth; + pDevModeOutput->dmPelsHeight = pdmwOutput->dmPelsHeight; + pDevModeOutput->dmDisplayFlags = pdmwOutput->dmDisplayFlags; + pDevModeOutput->dmNup = pdmwOutput->dmNup; + pDevModeOutput->dmDisplayFrequency = pdmwOutput->dmDisplayFrequency; + pDevModeOutput->dmICMMethod = pdmwOutput->dmICMMethod; + pDevModeOutput->dmICMIntent = pdmwOutput->dmICMIntent; + pDevModeOutput->dmMediaType = pdmwOutput->dmMediaType; + pDevModeOutput->dmDitherType = pdmwOutput->dmDitherType; + pDevModeOutput->dmReserved1 = pdmwOutput->dmReserved1; + pDevModeOutput->dmReserved2 = pdmwOutput->dmReserved2; + pDevModeOutput->dmPanningWidth = pdmwOutput->dmPanningWidth; + pDevModeOutput->dmPanningHeight = pdmwOutput->dmPanningHeight; + } + +Cleanup: + + if(pwszDeviceName) + HeapFree(hProcessHeap, 0, pwszDeviceName); + + if (pdmwInput) + HeapFree(hProcessHeap, 0, pdmwInput); + + if (pdmwOutput) + HeapFree(hProcessHeap, 0, pdmwOutput); + + return bReturnValue; } static PRINTER_INFO_9W * get_devmodeW(HANDLE hprn) From a7b9a4a576cfdda0a0e26644d5d270a8957a2b16 Mon Sep 17 00:00:00 2001 From: Doug Lyons Date: Fri, 14 Feb 2020 22:35:12 -0600 Subject: [PATCH 2/4] Refactor based on Colin's review comments. --- win32ss/printing/base/winspool/devmode.c | 101 ++++++++++++++++++++++ win32ss/printing/base/winspool/precomp.h | 5 ++ win32ss/printing/base/winspool/printers.c | 84 +----------------- 3 files changed, 108 insertions(+), 82 deletions(-) diff --git a/win32ss/printing/base/winspool/devmode.c b/win32ss/printing/base/winspool/devmode.c index b75932a313f..2605a7fa4d9 100644 --- a/win32ss/printing/base/winspool/devmode.c +++ b/win32ss/printing/base/winspool/devmode.c @@ -233,3 +233,104 @@ IsValidDevmodeW(PDEVMODEW pDevmode, size_t DevmodeSize) SetLastError(ERROR_INVALID_DATA); return FALSE; } + +void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pDevModeOutput) +{ + FIXME("This function should become ConvertAnsiDevModeToUnicodeDevmode when its parameters are known!\n"); + + // Check if a pDevModeInput and pDevModeOutput are both not NULL. + if (!pDevModeInput || !pDevModeOutput) + return; + + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmDeviceName, -1, pDevModeOutput->dmDeviceName, CCHDEVICENAME); + pDevModeOutput->dmSpecVersion = pDevModeInput->dmSpecVersion; + pDevModeOutput->dmDriverVersion = pDevModeInput->dmDriverVersion; + pDevModeOutput->dmSize = pDevModeInput->dmSize; + pDevModeOutput->dmDriverExtra = pDevModeInput->dmDriverExtra; + pDevModeOutput->dmFields = pDevModeInput->dmFields; + pDevModeOutput->dmOrientation = pDevModeInput->dmOrientation; + pDevModeOutput->dmPaperSize = pDevModeInput->dmPaperSize; + pDevModeOutput->dmPaperLength = pDevModeInput->dmPaperLength; + pDevModeOutput->dmPaperWidth = pDevModeInput->dmPaperWidth; + pDevModeOutput->dmScale = pDevModeInput->dmScale; + pDevModeOutput->dmCopies = pDevModeInput->dmCopies; + pDevModeOutput->dmDefaultSource = pDevModeInput->dmDefaultSource; + pDevModeOutput->dmPrintQuality = pDevModeInput->dmPrintQuality; + pDevModeOutput->dmPosition = pDevModeInput->dmPosition; + pDevModeOutput->dmDisplayOrientation = pDevModeInput->dmDisplayOrientation; + pDevModeOutput->dmDisplayFixedOutput = pDevModeInput->dmDisplayFixedOutput; + pDevModeOutput->dmColor = pDevModeInput->dmColor; + pDevModeOutput->dmDuplex = pDevModeInput->dmDuplex; + pDevModeOutput->dmYResolution = pDevModeInput->dmYResolution; + pDevModeOutput->dmTTOption = pDevModeInput->dmTTOption; + pDevModeOutput->dmCollate = pDevModeInput->dmCollate; + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmFormName, -1, pDevModeOutput->dmFormName, CCHFORMNAME); + pDevModeOutput->dmLogPixels = pDevModeInput->dmLogPixels; + pDevModeOutput->dmBitsPerPel = pDevModeInput->dmBitsPerPel; + pDevModeOutput->dmPelsWidth = pDevModeInput->dmPelsWidth; + pDevModeOutput->dmPelsHeight = pDevModeInput->dmPelsHeight; + pDevModeOutput->dmDisplayFlags = pDevModeInput->dmDisplayFlags; + pDevModeOutput->dmNup = pDevModeInput->dmNup; + pDevModeOutput->dmDisplayFrequency = pDevModeInput->dmDisplayFrequency; + pDevModeOutput->dmICMMethod = pDevModeInput->dmICMMethod; + pDevModeOutput->dmICMIntent = pDevModeInput->dmICMIntent; + pDevModeOutput->dmMediaType = pDevModeInput->dmMediaType; + pDevModeOutput->dmDitherType = pDevModeInput->dmDitherType; + pDevModeOutput->dmReserved1 = pDevModeInput->dmReserved1; + pDevModeOutput->dmReserved2 = pDevModeInput->dmReserved2; + pDevModeOutput->dmPanningWidth = pDevModeInput->dmPanningWidth; + pDevModeOutput->dmPanningHeight = pDevModeInput->dmPanningHeight; + + return; +} + + +void RosConvertUnicodeDevModeToAnsiDevmode(PDEVMODEW pDevModeInput, PDEVMODEA pDevModeOutput) +{ + FIXME("This function should become ConvertUnicodeDevModeToAnsiDevmode when its parameters are known!\n"); + + // Check if a pDevModeInput and pDevModeOutput are both not NULL. + if (!pDevModeInput || !pDevModeOutput) + return; + + WideCharToMultiByte(CP_ACP, 0, pDevModeInput->dmDeviceName, -1, (LPSTR)pDevModeOutput->dmDeviceName, CCHDEVICENAME, NULL, NULL); + pDevModeOutput->dmSpecVersion = pDevModeInput->dmSpecVersion; + pDevModeOutput->dmDriverVersion = pDevModeInput->dmDriverVersion; + pDevModeOutput->dmSize = pDevModeInput->dmSize; + pDevModeOutput->dmDriverExtra = pDevModeInput->dmDriverExtra; + pDevModeOutput->dmFields = pDevModeInput->dmFields; + pDevModeOutput->dmOrientation = pDevModeInput->dmOrientation; + pDevModeOutput->dmPaperSize = pDevModeInput->dmPaperSize; + pDevModeOutput->dmPaperLength = pDevModeInput->dmPaperLength; + pDevModeOutput->dmPaperWidth = pDevModeInput->dmPaperWidth; + pDevModeOutput->dmScale = pDevModeInput->dmScale; + pDevModeOutput->dmCopies = pDevModeInput->dmCopies; + pDevModeOutput->dmDefaultSource = pDevModeInput->dmDefaultSource; + pDevModeOutput->dmPrintQuality = pDevModeInput->dmPrintQuality; + pDevModeOutput->dmPosition = pDevModeInput->dmPosition; + pDevModeOutput->dmDisplayOrientation = pDevModeInput->dmDisplayOrientation; + pDevModeOutput->dmDisplayFixedOutput = pDevModeInput->dmDisplayFixedOutput; + pDevModeOutput->dmColor = pDevModeInput->dmColor; + pDevModeOutput->dmDuplex = pDevModeInput->dmDuplex; + pDevModeOutput->dmYResolution = pDevModeInput->dmYResolution; + pDevModeOutput->dmTTOption = pDevModeInput->dmTTOption; + pDevModeOutput->dmCollate = pDevModeInput->dmCollate; + WideCharToMultiByte(CP_ACP, 0, pDevModeInput->dmFormName, -1, (LPSTR)pDevModeOutput->dmFormName, CCHFORMNAME, NULL, NULL); + pDevModeOutput->dmLogPixels = pDevModeInput->dmLogPixels; + pDevModeOutput->dmBitsPerPel = pDevModeInput->dmBitsPerPel; + pDevModeOutput->dmPelsWidth = pDevModeInput->dmPelsWidth; + pDevModeOutput->dmPelsHeight = pDevModeInput->dmPelsHeight; + pDevModeOutput->dmDisplayFlags = pDevModeInput->dmDisplayFlags; + pDevModeOutput->dmNup = pDevModeInput->dmNup; + pDevModeOutput->dmDisplayFrequency = pDevModeInput->dmDisplayFrequency; + pDevModeOutput->dmICMMethod = pDevModeInput->dmICMMethod; + pDevModeOutput->dmICMIntent = pDevModeInput->dmICMIntent; + pDevModeOutput->dmMediaType = pDevModeInput->dmMediaType; + pDevModeOutput->dmDitherType = pDevModeInput->dmDitherType; + pDevModeOutput->dmReserved1 = pDevModeInput->dmReserved1; + pDevModeOutput->dmReserved2 = pDevModeInput->dmReserved2; + pDevModeOutput->dmPanningWidth = pDevModeInput->dmPanningWidth; + pDevModeOutput->dmPanningHeight = pDevModeInput->dmPanningHeight; + + return; +} \ No newline at end of file diff --git a/win32ss/printing/base/winspool/precomp.h b/win32ss/printing/base/winspool/precomp.h index cae8bd320e8..58eed626d02 100644 --- a/win32ss/printing/base/winspool/precomp.h +++ b/win32ss/printing/base/winspool/precomp.h @@ -44,4 +44,9 @@ extern HANDLE hProcessHeap; // utils.c extern BOOL UnicodeToAnsiInPlace(PWSTR pwszField); +// devmode.c +extern void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pDevModeOutput); + +extern void RosConvertUnicodeDevModeToAnsiDevmode(PDEVMODEW pDevModeInput, PDEVMODEA pDevModeOutput); + #endif diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index 3b37e06c5d4..c9a578c7b17 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -239,47 +239,7 @@ DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDe ERR("HeapAlloc failed!\n"); goto Cleanup; } - - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmDeviceName, -1, pdmwInput->dmDeviceName, CCHDEVICENAME); - pdmwInput->dmSpecVersion = pDevModeInput->dmSpecVersion; - pdmwInput->dmDriverVersion = pDevModeInput->dmDriverVersion; - pdmwInput->dmSize = pDevModeInput->dmSize; - pdmwInput->dmDriverExtra = pDevModeInput->dmDriverExtra; - pdmwInput->dmFields = pDevModeInput->dmFields; - pdmwInput->dmOrientation = pDevModeInput->dmOrientation; - pdmwInput->dmPaperSize = pDevModeInput->dmPaperSize; - pdmwInput->dmPaperLength = pDevModeInput->dmPaperLength; - pdmwInput->dmPaperWidth = pDevModeInput->dmPaperWidth; - pdmwInput->dmScale = pDevModeInput->dmScale; - pdmwInput->dmCopies = pDevModeInput->dmCopies; - pdmwInput->dmDefaultSource = pDevModeInput->dmDefaultSource; - pdmwInput->dmPrintQuality = pDevModeInput->dmPrintQuality; - pdmwInput->dmPosition = pDevModeInput->dmPosition; - pdmwInput->dmDisplayOrientation = pDevModeInput->dmDisplayOrientation; - pdmwInput->dmDisplayFixedOutput = pDevModeInput->dmDisplayFixedOutput; - pdmwInput->dmColor = pDevModeInput->dmColor; - pdmwInput->dmDuplex = pDevModeInput->dmDuplex; - pdmwInput->dmYResolution = pDevModeInput->dmYResolution; - pdmwInput->dmTTOption = pDevModeInput->dmTTOption; - pdmwInput->dmCollate = pDevModeInput->dmCollate; - - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmFormName, -1, pdmwInput->dmFormName, CCHFORMNAME); - - pdmwInput->dmLogPixels = pDevModeInput->dmLogPixels; - pdmwInput->dmBitsPerPel = pDevModeInput->dmBitsPerPel; - pdmwInput->dmPelsWidth = pDevModeInput->dmPelsWidth; - pdmwInput->dmPelsHeight = pDevModeInput->dmPelsHeight; - pdmwInput->dmDisplayFlags = pDevModeInput->dmDisplayFlags; - pdmwInput->dmNup = pDevModeInput->dmNup; - pdmwInput->dmDisplayFrequency = pDevModeInput->dmDisplayFrequency; - pdmwInput->dmICMMethod = pDevModeInput->dmICMMethod; - pdmwInput->dmICMIntent = pDevModeInput->dmICMIntent; - pdmwInput->dmMediaType = pDevModeInput->dmMediaType; - pdmwInput->dmDitherType = pDevModeInput->dmDitherType; - pdmwInput->dmReserved1 = pDevModeInput->dmReserved1; - pdmwInput->dmReserved2 = pDevModeInput->dmReserved2; - pdmwInput->dmPanningWidth = pDevModeInput->dmPanningWidth; - pdmwInput->dmPanningHeight = pDevModeInput->dmPanningHeight; + RosConvertAnsiDevModeToUnicodeDevmode(pDevModeInput, pdmwInput); } if (pDevModeOutput) @@ -310,47 +270,7 @@ DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDe if (pdmwOutput) { - WideCharToMultiByte(CP_ACP, 0, pdmwOutput->dmDeviceName, -1, (LPSTR)pDevModeOutput->dmDeviceName, CCHDEVICENAME, NULL, NULL); - - pDevModeOutput->dmSpecVersion = pdmwOutput->dmSpecVersion; - pDevModeOutput->dmDriverVersion = pdmwOutput->dmDriverVersion; - pDevModeOutput->dmSize = pdmwOutput->dmSize; - pDevModeOutput->dmDriverExtra = pdmwOutput->dmDriverExtra; - pDevModeOutput->dmFields = pdmwOutput->dmFields; - pDevModeOutput->dmOrientation = pdmwOutput->dmOrientation; - pDevModeOutput->dmPaperSize = pdmwOutput->dmPaperSize; - pDevModeOutput->dmPaperLength = pdmwOutput->dmPaperLength; - pDevModeOutput->dmPaperWidth = pdmwOutput->dmPaperWidth; - pDevModeOutput->dmScale = pdmwOutput->dmScale; - pDevModeOutput->dmCopies = pdmwOutput->dmCopies; - pDevModeOutput->dmDefaultSource = pdmwOutput->dmDefaultSource; - pDevModeOutput->dmPrintQuality = pdmwOutput->dmPrintQuality; - pDevModeOutput->dmPosition = pdmwOutput->dmPosition; - pDevModeOutput->dmDisplayOrientation = pdmwOutput->dmDisplayOrientation; - pDevModeOutput->dmDisplayFixedOutput = pdmwOutput->dmDisplayFixedOutput; - pDevModeOutput->dmColor = pdmwOutput->dmColor; - pDevModeOutput->dmDuplex = pdmwOutput->dmDuplex; - pDevModeOutput->dmYResolution = pdmwOutput->dmYResolution; - pDevModeOutput->dmTTOption = pdmwOutput->dmTTOption; - pDevModeOutput->dmCollate = pdmwOutput->dmCollate; - - WideCharToMultiByte(CP_ACP, 0, pdmwOutput->dmFormName, -1, (LPSTR)pDevModeOutput->dmFormName, CCHFORMNAME, NULL, NULL); - - pDevModeOutput->dmLogPixels = pdmwOutput->dmLogPixels; - pDevModeOutput->dmBitsPerPel = pdmwOutput->dmBitsPerPel; - pDevModeOutput->dmPelsWidth = pdmwOutput->dmPelsWidth; - pDevModeOutput->dmPelsHeight = pdmwOutput->dmPelsHeight; - pDevModeOutput->dmDisplayFlags = pdmwOutput->dmDisplayFlags; - pDevModeOutput->dmNup = pdmwOutput->dmNup; - pDevModeOutput->dmDisplayFrequency = pdmwOutput->dmDisplayFrequency; - pDevModeOutput->dmICMMethod = pdmwOutput->dmICMMethod; - pDevModeOutput->dmICMIntent = pdmwOutput->dmICMIntent; - pDevModeOutput->dmMediaType = pdmwOutput->dmMediaType; - pDevModeOutput->dmDitherType = pdmwOutput->dmDitherType; - pDevModeOutput->dmReserved1 = pdmwOutput->dmReserved1; - pDevModeOutput->dmReserved2 = pdmwOutput->dmReserved2; - pDevModeOutput->dmPanningWidth = pdmwOutput->dmPanningWidth; - pDevModeOutput->dmPanningHeight = pdmwOutput->dmPanningHeight; + RosConvertUnicodeDevModeToAnsiDevmode(pdmwOutput, pDevModeOutput); } Cleanup: From 7dfc0654a1fd2cf70a7776e78ce2ff21f025e032 Mon Sep 17 00:00:00 2001 From: Doug Lyons Date: Sun, 23 Feb 2020 20:41:13 -0600 Subject: [PATCH 3/4] Retry using GdiConvertToDevmodeA and GdiConvertToDevmodeW (new function) --- win32ss/gdi/gdi32/include/precomp.h | 3 + win32ss/printing/base/winspool/devmode.c | 122 ++++++++--------------- 2 files changed, 47 insertions(+), 78 deletions(-) diff --git a/win32ss/gdi/gdi32/include/precomp.h b/win32ss/gdi/gdi32/include/precomp.h index 3d4b823c2fe..26e9dacafd8 100644 --- a/win32ss/gdi/gdi32/include/precomp.h +++ b/win32ss/gdi/gdi32/include/precomp.h @@ -60,4 +60,7 @@ #include #include +// misc/misc.c +extern DEVMODEW * WINAPI GdiConvertToDevmodeW(const DEVMODEA *dmA); + #endif /* _GDI32_PCH_ */ diff --git a/win32ss/printing/base/winspool/devmode.c b/win32ss/printing/base/winspool/devmode.c index 2605a7fa4d9..2b5b6aeb807 100644 --- a/win32ss/printing/base/winspool/devmode.c +++ b/win32ss/printing/base/winspool/devmode.c @@ -242,48 +242,52 @@ void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pD if (!pDevModeInput || !pDevModeOutput) return; - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmDeviceName, -1, pDevModeOutput->dmDeviceName, CCHDEVICENAME); - pDevModeOutput->dmSpecVersion = pDevModeInput->dmSpecVersion; - pDevModeOutput->dmDriverVersion = pDevModeInput->dmDriverVersion; - pDevModeOutput->dmSize = pDevModeInput->dmSize; - pDevModeOutput->dmDriverExtra = pDevModeInput->dmDriverExtra; - pDevModeOutput->dmFields = pDevModeInput->dmFields; - pDevModeOutput->dmOrientation = pDevModeInput->dmOrientation; - pDevModeOutput->dmPaperSize = pDevModeInput->dmPaperSize; - pDevModeOutput->dmPaperLength = pDevModeInput->dmPaperLength; - pDevModeOutput->dmPaperWidth = pDevModeInput->dmPaperWidth; - pDevModeOutput->dmScale = pDevModeInput->dmScale; - pDevModeOutput->dmCopies = pDevModeInput->dmCopies; - pDevModeOutput->dmDefaultSource = pDevModeInput->dmDefaultSource; - pDevModeOutput->dmPrintQuality = pDevModeInput->dmPrintQuality; - pDevModeOutput->dmPosition = pDevModeInput->dmPosition; - pDevModeOutput->dmDisplayOrientation = pDevModeInput->dmDisplayOrientation; - pDevModeOutput->dmDisplayFixedOutput = pDevModeInput->dmDisplayFixedOutput; - pDevModeOutput->dmColor = pDevModeInput->dmColor; - pDevModeOutput->dmDuplex = pDevModeInput->dmDuplex; - pDevModeOutput->dmYResolution = pDevModeInput->dmYResolution; - pDevModeOutput->dmTTOption = pDevModeInput->dmTTOption; - pDevModeOutput->dmCollate = pDevModeInput->dmCollate; - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDevModeInput->dmFormName, -1, pDevModeOutput->dmFormName, CCHFORMNAME); - pDevModeOutput->dmLogPixels = pDevModeInput->dmLogPixels; - pDevModeOutput->dmBitsPerPel = pDevModeInput->dmBitsPerPel; - pDevModeOutput->dmPelsWidth = pDevModeInput->dmPelsWidth; - pDevModeOutput->dmPelsHeight = pDevModeInput->dmPelsHeight; - pDevModeOutput->dmDisplayFlags = pDevModeInput->dmDisplayFlags; - pDevModeOutput->dmNup = pDevModeInput->dmNup; - pDevModeOutput->dmDisplayFrequency = pDevModeInput->dmDisplayFrequency; - pDevModeOutput->dmICMMethod = pDevModeInput->dmICMMethod; - pDevModeOutput->dmICMIntent = pDevModeInput->dmICMIntent; - pDevModeOutput->dmMediaType = pDevModeInput->dmMediaType; - pDevModeOutput->dmDitherType = pDevModeInput->dmDitherType; - pDevModeOutput->dmReserved1 = pDevModeInput->dmReserved1; - pDevModeOutput->dmReserved2 = pDevModeInput->dmReserved2; - pDevModeOutput->dmPanningWidth = pDevModeInput->dmPanningWidth; - pDevModeOutput->dmPanningHeight = pDevModeInput->dmPanningHeight; - + pDevModeOutput = GdiConvertToDevmodeW(pDevModeInput); return; } +DEVMODEA * +GdiConvertToDevmodeA(const DEVMODEW *dmW) +{ + DEVMODEA *dmA; + WORD dmA_size, dmW_size; + + dmW_size = dmW->dmSize; + + /* this is the minimal dmSize that XP accepts */ + if (dmW_size < FIELD_OFFSET(DEVMODEW, dmFields)) + return NULL; + + if (dmW_size > sizeof(DEVMODEW)) + dmW_size = sizeof(DEVMODEW); + + dmA_size = dmW_size - CCHDEVICENAME; + if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME) + dmA_size -= CCHFORMNAME * sizeof(WCHAR); + + dmA = HeapAlloc(GetProcessHeap(), 0, dmA_size + dmW->dmDriverExtra); + if (!dmA) return NULL; + + WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, (LPSTR) dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL); + + /* copy slightly more, to avoid long computations */ + memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, dmW_size - (CCHDEVICENAME * sizeof(WCHAR))); + + if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + (CCHFORMNAME * sizeof(WCHAR))) + { + WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, (LPSTR) dmA->dmFormName, CCHDEVICENAME, NULL, NULL); + + if (dmW_size > FIELD_OFFSET(DEVMODEW, dmLogPixels)) + memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW_size - FIELD_OFFSET(DEVMODEW, dmLogPixels)); + } + + if (dmW->dmDriverExtra) + memcpy((char *)dmA + dmW_size, (const char *)dmW + dmW_size, dmW->dmDriverExtra); + + dmA->dmSize = dmA_size; + + return dmA; +} void RosConvertUnicodeDevModeToAnsiDevmode(PDEVMODEW pDevModeInput, PDEVMODEA pDevModeOutput) { @@ -293,44 +297,6 @@ void RosConvertUnicodeDevModeToAnsiDevmode(PDEVMODEW pDevModeInput, PDEVMODEA pD if (!pDevModeInput || !pDevModeOutput) return; - WideCharToMultiByte(CP_ACP, 0, pDevModeInput->dmDeviceName, -1, (LPSTR)pDevModeOutput->dmDeviceName, CCHDEVICENAME, NULL, NULL); - pDevModeOutput->dmSpecVersion = pDevModeInput->dmSpecVersion; - pDevModeOutput->dmDriverVersion = pDevModeInput->dmDriverVersion; - pDevModeOutput->dmSize = pDevModeInput->dmSize; - pDevModeOutput->dmDriverExtra = pDevModeInput->dmDriverExtra; - pDevModeOutput->dmFields = pDevModeInput->dmFields; - pDevModeOutput->dmOrientation = pDevModeInput->dmOrientation; - pDevModeOutput->dmPaperSize = pDevModeInput->dmPaperSize; - pDevModeOutput->dmPaperLength = pDevModeInput->dmPaperLength; - pDevModeOutput->dmPaperWidth = pDevModeInput->dmPaperWidth; - pDevModeOutput->dmScale = pDevModeInput->dmScale; - pDevModeOutput->dmCopies = pDevModeInput->dmCopies; - pDevModeOutput->dmDefaultSource = pDevModeInput->dmDefaultSource; - pDevModeOutput->dmPrintQuality = pDevModeInput->dmPrintQuality; - pDevModeOutput->dmPosition = pDevModeInput->dmPosition; - pDevModeOutput->dmDisplayOrientation = pDevModeInput->dmDisplayOrientation; - pDevModeOutput->dmDisplayFixedOutput = pDevModeInput->dmDisplayFixedOutput; - pDevModeOutput->dmColor = pDevModeInput->dmColor; - pDevModeOutput->dmDuplex = pDevModeInput->dmDuplex; - pDevModeOutput->dmYResolution = pDevModeInput->dmYResolution; - pDevModeOutput->dmTTOption = pDevModeInput->dmTTOption; - pDevModeOutput->dmCollate = pDevModeInput->dmCollate; - WideCharToMultiByte(CP_ACP, 0, pDevModeInput->dmFormName, -1, (LPSTR)pDevModeOutput->dmFormName, CCHFORMNAME, NULL, NULL); - pDevModeOutput->dmLogPixels = pDevModeInput->dmLogPixels; - pDevModeOutput->dmBitsPerPel = pDevModeInput->dmBitsPerPel; - pDevModeOutput->dmPelsWidth = pDevModeInput->dmPelsWidth; - pDevModeOutput->dmPelsHeight = pDevModeInput->dmPelsHeight; - pDevModeOutput->dmDisplayFlags = pDevModeInput->dmDisplayFlags; - pDevModeOutput->dmNup = pDevModeInput->dmNup; - pDevModeOutput->dmDisplayFrequency = pDevModeInput->dmDisplayFrequency; - pDevModeOutput->dmICMMethod = pDevModeInput->dmICMMethod; - pDevModeOutput->dmICMIntent = pDevModeInput->dmICMIntent; - pDevModeOutput->dmMediaType = pDevModeInput->dmMediaType; - pDevModeOutput->dmDitherType = pDevModeInput->dmDitherType; - pDevModeOutput->dmReserved1 = pDevModeInput->dmReserved1; - pDevModeOutput->dmReserved2 = pDevModeInput->dmReserved2; - pDevModeOutput->dmPanningWidth = pDevModeInput->dmPanningWidth; - pDevModeOutput->dmPanningHeight = pDevModeInput->dmPanningHeight; - + pDevModeOutput = GdiConvertToDevmodeA(pDevModeInput); return; } \ No newline at end of file From 09395d579dab8c276a66d6d1f021f2be1c55813b Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Mon, 24 Feb 2020 20:59:27 +0100 Subject: [PATCH 4/4] Fix a few things, add comments to the non-trivial DEVMODE conversion function, and adapt to the latest changes in master. --- win32ss/gdi/gdi32/include/precomp.h | 3 -- win32ss/printing/base/winspool/devmode.c | 44 ++++++++++++++--------- win32ss/printing/base/winspool/printers.c | 3 +- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/win32ss/gdi/gdi32/include/precomp.h b/win32ss/gdi/gdi32/include/precomp.h index 26e9dacafd8..3d4b823c2fe 100644 --- a/win32ss/gdi/gdi32/include/precomp.h +++ b/win32ss/gdi/gdi32/include/precomp.h @@ -60,7 +60,4 @@ #include #include -// misc/misc.c -extern DEVMODEW * WINAPI GdiConvertToDevmodeW(const DEVMODEA *dmA); - #endif /* _GDI32_PCH_ */ diff --git a/win32ss/printing/base/winspool/devmode.c b/win32ss/printing/base/winspool/devmode.c index 2b5b6aeb807..c97f0e9ff58 100644 --- a/win32ss/printing/base/winspool/devmode.c +++ b/win32ss/printing/base/winspool/devmode.c @@ -236,21 +236,22 @@ IsValidDevmodeW(PDEVMODEW pDevmode, size_t DevmodeSize) void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pDevModeOutput) { - FIXME("This function should become ConvertAnsiDevModeToUnicodeDevmode when its parameters are known!\n"); + // FIXME: This function should become ConvertAnsiDevModeToUnicodeDevmode when its parameters are known! // Check if a pDevModeInput and pDevModeOutput are both not NULL. if (!pDevModeInput || !pDevModeOutput) return; pDevModeOutput = GdiConvertToDevmodeW(pDevModeInput); - return; } -DEVMODEA * -GdiConvertToDevmodeA(const DEVMODEW *dmW) +// Internal counterpart to GdiConvertToDevmodeW from gdi32 +static __inline DEVMODEA* +_ConvertToDevmodeA(const DEVMODEW *dmW) { DEVMODEA *dmA; WORD dmA_size, dmW_size; + size_t BytesToCopy; dmW_size = dmW->dmSize; @@ -258,32 +259,44 @@ GdiConvertToDevmodeA(const DEVMODEW *dmW) if (dmW_size < FIELD_OFFSET(DEVMODEW, dmFields)) return NULL; + // Guard against callers that set dmSize incorrectly. if (dmW_size > sizeof(DEVMODEW)) dmW_size = sizeof(DEVMODEW); + // dmA_size must become dmW_size without the additional 1 byte per character for each Unicode string (dmDeviceName and dmFormName). dmA_size = dmW_size - CCHDEVICENAME; - if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME) - dmA_size -= CCHFORMNAME * sizeof(WCHAR); + if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME * sizeof(WCHAR)) + dmA_size -= CCHFORMNAME; + // Allocate the required bytes, that is dmSize for the ANSI DEVMODEA structure plus any extra bytes requested through dmDriverExtra. dmA = HeapAlloc(GetProcessHeap(), 0, dmA_size + dmW->dmDriverExtra); if (!dmA) return NULL; - WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, (LPSTR) dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL); + // Every valid DEVMODEW has a dmDeviceName, which we convert to ANSI here. + WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, (LPSTR)dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL); - /* copy slightly more, to avoid long computations */ - memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, dmW_size - (CCHDEVICENAME * sizeof(WCHAR))); + // Copy everything up to dmFormName or the remaining dmW_size, whatever is smaller. + BytesToCopy = min(FIELD_OFFSET(DEVMODEW, dmFormName) - FIELD_OFFSET(DEVMODEW, dmSpecVersion), dmW_size - CCHDEVICENAME * sizeof(WCHAR)); + memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, BytesToCopy); - if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + (CCHFORMNAME * sizeof(WCHAR))) + // Handle dmFormName if the input DEVMODEW is large enough to contain one. + if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME * sizeof(WCHAR)) { - WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, (LPSTR) dmA->dmFormName, CCHDEVICENAME, NULL, NULL); + if (dmW->dmFields & DM_FORMNAME) + WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, (LPSTR)dmA->dmFormName, CCHFORMNAME, NULL, NULL); + else + dmA->dmFormName[0] = 0; + // Copy the remaining fields. if (dmW_size > FIELD_OFFSET(DEVMODEW, dmLogPixels)) memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW_size - FIELD_OFFSET(DEVMODEW, dmLogPixels)); } + // Append dmDriverExtra if required. if (dmW->dmDriverExtra) - memcpy((char *)dmA + dmW_size, (const char *)dmW + dmW_size, dmW->dmDriverExtra); + memcpy((char *)dmA + dmA_size, (const char *)dmW + dmW_size, dmW->dmDriverExtra); + // Set the corrected dmSize and we are done. dmA->dmSize = dmA_size; return dmA; @@ -291,12 +304,11 @@ GdiConvertToDevmodeA(const DEVMODEW *dmW) void RosConvertUnicodeDevModeToAnsiDevmode(PDEVMODEW pDevModeInput, PDEVMODEA pDevModeOutput) { - FIXME("This function should become ConvertUnicodeDevModeToAnsiDevmode when its parameters are known!\n"); + // FIXME: This function should become ConvertUnicodeDevModeToAnsiDevmode when its parameters are known! // Check if a pDevModeInput and pDevModeOutput are both not NULL. if (!pDevModeInput || !pDevModeOutput) return; - pDevModeOutput = GdiConvertToDevmodeA(pDevModeInput); - return; -} \ No newline at end of file + pDevModeOutput = _ConvertToDevmodeA(pDevModeInput); +} diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index c9a578c7b17..4180dfb3d1c 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -270,11 +270,10 @@ DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDe if (pdmwOutput) { - RosConvertUnicodeDevModeToAnsiDevmode(pdmwOutput, pDevModeOutput); + RosConvertUnicodeDevModeToAnsiDevmode(pdmwOutput, pDevModeOutput); } Cleanup: - if(pwszDeviceName) HeapFree(hProcessHeap, 0, pwszDeviceName);