From adffa8ea7591f4d2d6530a82361d419a9ffc8ad7 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 31 Jan 2020 17:38:47 -0600 Subject: [PATCH] [Printing] Part of GDI Support Fix ups and added support to prevent GDI from crashing. These functions will be required for GDI. Part 1 of print support. --- .../printing/base/spoolsv/printerdrivers.c | 4 +- win32ss/printing/base/winspool/precomp.h | 1 + win32ss/printing/base/winspool/printers.c | 20 ++- win32ss/printing/base/winspool/winspool.spec | 4 +- .../include/marshalling/printerdrivers.h | 30 +++++ .../providers/localspl/printerdrivers.c | 119 +++++++++++++++++- 6 files changed, 169 insertions(+), 9 deletions(-) diff --git a/win32ss/printing/base/spoolsv/printerdrivers.c b/win32ss/printing/base/spoolsv/printerdrivers.c index a1f45865c15..ae85f84434d 100644 --- a/win32ss/printing/base/spoolsv/printerdrivers.c +++ b/win32ss/printing/base/spoolsv/printerdrivers.c @@ -49,6 +49,8 @@ _RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWOR DWORD dwErrorCode; PBYTE pDriverAligned; + ERR("_RpcGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded); + dwErrorCode = RpcImpersonateClient(NULL); if (dwErrorCode != ERROR_SUCCESS) { @@ -61,7 +63,7 @@ _RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWOR if (GetPrinterDriverW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded)) { // Replace relative offset addresses in the output by absolute pointers. - ASSERT(Level >= 1 && Level <= 3); + ASSERT(Level >= 1 && Level <= 5); MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); } else diff --git a/win32ss/printing/base/winspool/precomp.h b/win32ss/printing/base/winspool/precomp.h index cbfaac933ca..033b38d1b4c 100644 --- a/win32ss/printing/base/winspool/precomp.h +++ b/win32ss/printing/base/winspool/precomp.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index 7fd34a40866..0e7729408b6 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -194,6 +194,14 @@ DeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort, WORD fwCapability, LPWSTR pO return 0; } +INT WINAPI +DocumentEvent( HANDLE hPrinter, HDC hdc, int iEsc, ULONG cbIn, PVOID pvIn, ULONG cbOut, PVOID pvOut) +{ + ERR("DocumentEvent(%p, %p, %lu, %lu, %p, %lu, %p)\n", hPrinter, hdc, iEsc, cbIn, pvIn, cbOut, pvOut); + UNIMPLEMENTED; + return DOCUMENTEVENT_UNSUPPORTED; +} + LONG WINAPI DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput, DWORD fMode) { @@ -1042,7 +1050,7 @@ GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDri DWORD dwErrorCode; PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; - TRACE("GetPrinterDriverW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); + ERR("GetPrinterDriverW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); // Sanity checks. if (!pHandle) @@ -1076,7 +1084,7 @@ GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDri if (dwErrorCode == ERROR_SUCCESS) { // Replace relative offset addresses in the output by absolute pointers. - ASSERT(Level <= 3); + ASSERT(Level <= 5); MarshallUpStructure(cbBuf, pDriverInfo, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); } @@ -1472,6 +1480,14 @@ SetPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pPrinter, DWORD Command) return FALSE; } +BOOL WINAPI +SplDriverUnloadComplete(LPWSTR pDriverFile) +{ + ERR("DriverUnloadComplete(%S)\n", pDriverFile); + UNIMPLEMENTED; + return TRUE; // return true for now. +} + DWORD WINAPI StartDocPrinterA(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo) { diff --git a/win32ss/printing/base/winspool/winspool.spec b/win32ss/printing/base/winspool/winspool.spec index 7c2888b236b..318a2df8ca9 100644 --- a/win32ss/printing/base/winspool/winspool.spec +++ b/win32ss/printing/base/winspool/winspool.spec @@ -74,7 +74,7 @@ 173 stdcall DeviceCapabilitiesW(wstr wstr long ptr ptr) 174 stub DeviceMode 175 stub DevicePropertySheets -176 stub DocumentEvent +176 stdcall DocumentEvent(ptr ptr long long ptr long ptr) 177 stdcall DocumentPropertiesA(ptr ptr ptr ptr ptr long) 178 stdcall DocumentPropertiesW(ptr ptr ptr ptr ptr long) 179 stub DocumentPropertySheets @@ -186,7 +186,7 @@ 285 stdcall SetPrinterDataExW(ptr wstr wstr long ptr long) 286 stdcall SetPrinterDataW(ptr wstr long ptr long) 287 stdcall SetPrinterW(ptr long ptr long) -288 stub SplDriverUnloadComplete +288 stdcall SplDriverUnloadComplete(ptr) 289 stub SpoolerDevQueryPrintW 290 stdcall SpoolerInit() 291 stub SpoolerPrinterEvent diff --git a/win32ss/printing/include/marshalling/printerdrivers.h b/win32ss/printing/include/marshalling/printerdrivers.h index 49951bdca27..ffaf50fa21c 100644 --- a/win32ss/printing/include/marshalling/printerdrivers.h +++ b/win32ss/printing/include/marshalling/printerdrivers.h @@ -41,6 +41,34 @@ static const MARSHALLING PrinterDriver3Marshalling = { } }; +static const MARSHALLING PrinterDriver4Marshalling = { + sizeof(DRIVER_INFO_4W), + { + { FIELD_OFFSET(DRIVER_INFO_4W, pName), RTL_FIELD_SIZE(DRIVER_INFO_4W, pName), RTL_FIELD_SIZE(DRIVER_INFO_4W, pName), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_4W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_4W, pEnvironment), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDriverPath), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDataFile), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_4W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_4W, pConfigFile), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pHelpFile), RTL_FIELD_SIZE(DRIVER_INFO_4W, pHelpFile), RTL_FIELD_SIZE(DRIVER_INFO_4W, pHelpFile), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pDependentFiles), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDependentFiles), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDependentFiles), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pMonitorName), RTL_FIELD_SIZE(DRIVER_INFO_4W, pMonitorName), RTL_FIELD_SIZE(DRIVER_INFO_4W, pMonitorName), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pDefaultDataType), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDefaultDataType), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDefaultDataType), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_4W, pszzPreviousNames), RTL_FIELD_SIZE(DRIVER_INFO_4W, pszzPreviousNames), RTL_FIELD_SIZE(DRIVER_INFO_4W, pDefaultDataType), TRUE }, + { MAXDWORD, 0, 0, FALSE } + } +}; + +static const MARSHALLING PrinterDriver5Marshalling = { + sizeof(DRIVER_INFO_5W), + { + { FIELD_OFFSET(DRIVER_INFO_5W, pName), RTL_FIELD_SIZE(DRIVER_INFO_5W, pName), RTL_FIELD_SIZE(DRIVER_INFO_5W, pName), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_5W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_5W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_5W, pEnvironment), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_5W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_5W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_5W, pDriverPath), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_5W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_5W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_5W, pDataFile), TRUE }, + { FIELD_OFFSET(DRIVER_INFO_5W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_5W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_5W, pConfigFile), TRUE }, + { MAXDWORD, 0, 0, FALSE } + } +}; static const MARSHALLING* pPrinterDriverMarshalling[] = { @@ -48,4 +76,6 @@ static const MARSHALLING* pPrinterDriverMarshalling[] = { &PrinterDriver1Marshalling, &PrinterDriver2Marshalling, &PrinterDriver3Marshalling, + &PrinterDriver4Marshalling, + &PrinterDriver5Marshalling, }; diff --git a/win32ss/printing/providers/localspl/printerdrivers.c b/win32ss/printing/providers/localspl/printerdrivers.c index 5bb5b3db73a..351667cecc8 100644 --- a/win32ss/printing/providers/localspl/printerdrivers.c +++ b/win32ss/printing/providers/localspl/printerdrivers.c @@ -7,7 +7,6 @@ #include "precomp.h" - // Local Constants static DWORD dwDriverInfo1Offsets[] = { FIELD_OFFSET(DRIVER_INFO_1W, pName), @@ -36,6 +35,29 @@ static DWORD dwDriverInfo3Offsets[] = { MAXDWORD }; +static DWORD dwDriverInfo4Offsets[] = { + FIELD_OFFSET(DRIVER_INFO_4W, pName), + FIELD_OFFSET(DRIVER_INFO_4W, pEnvironment), + FIELD_OFFSET(DRIVER_INFO_4W, pDriverPath), + FIELD_OFFSET(DRIVER_INFO_4W, pDataFile), + FIELD_OFFSET(DRIVER_INFO_4W, pConfigFile), + FIELD_OFFSET(DRIVER_INFO_4W, pHelpFile), + FIELD_OFFSET(DRIVER_INFO_4W, pDependentFiles), + FIELD_OFFSET(DRIVER_INFO_4W, pMonitorName), + FIELD_OFFSET(DRIVER_INFO_4W, pDefaultDataType), + FIELD_OFFSET(DRIVER_INFO_4W, pszzPreviousNames), + MAXDWORD +}; + +static DWORD dwDriverInfo5Offsets[] = { + FIELD_OFFSET(DRIVER_INFO_5W, pName), + FIELD_OFFSET(DRIVER_INFO_5W, pEnvironment), + FIELD_OFFSET(DRIVER_INFO_5W, pDriverPath), + FIELD_OFFSET(DRIVER_INFO_5W, pDataFile), + FIELD_OFFSET(DRIVER_INFO_5W, pConfigFile), + MAXDWORD +}; + static void ToMultiSz(LPWSTR pString) { @@ -118,7 +140,7 @@ _LocalGetPrinterDriverLevel3(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_3W* ppD pwszStrings[1] = wszCurrentEnvironment; // pEnvironment pwszStrings[2] = L"c:\\reactos\\system32\\localspl.dll"; // pDriverPath pwszStrings[3] = L"c:\\reactos\\system32\\localspl.dll"; // pDataFile - pwszStrings[4] = L"c:\\reactos\\system32\\printui.dll"; // pConfigFile + pwszStrings[4] = L"c:\\reactos\\system32\\printui.dll"; // pConfigFile pwszStrings[5] = L""; // pHelpFile pwszStrings[6] = L"localspl.dll|printui.dll|"; // pDependentFiles, | is separator and terminator! pwszStrings[7] = NULL; // pMonitorName @@ -148,6 +170,87 @@ _LocalGetPrinterDriverLevel3(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_3W* ppD (*ppDriverInfo)++; } +static void +_LocalGetPrinterDriverLevel4(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_4W* ppDriverInfo, PBYTE* ppDriverInfoEnd, PDWORD pcbNeeded) +{ + DWORD n; + PCWSTR pwszStrings[10]; + + /* Clearly these things should not be hardcoded, so when it is needed, someone can add meaningfull values here */ + pwszStrings[0] = pHandle->pPrinter->pwszPrinterDriver; // pName + pwszStrings[1] = wszCurrentEnvironment; // pEnvironment + pwszStrings[2] = L"c:\\reactos\\system32\\localspl.dll"; // pDriverPath + pwszStrings[3] = L"c:\\reactos\\system32\\localspl.dll"; // pDataFile + pwszStrings[4] = L"c:\\reactos\\system32\\printui.dll"; // pConfigFile + pwszStrings[5] = L""; // pHelpFile + pwszStrings[6] = L"localspl.dll|printui.dll|"; // pDependentFiles, | is separator and terminator! + pwszStrings[7] = NULL; // pMonitorName + pwszStrings[8] = NULL; // pDefaultDataType + pwszStrings[9] = NULL; // pszzPreviousNames + + // Calculate the string lengths. + if (!ppDriverInfo) + { + for (n = 0; n < _countof(pwszStrings); ++n) + { + if (pwszStrings[n]) + { + *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR); + } + } + + *pcbNeeded += sizeof(DRIVER_INFO_4W); + return; + } + + (*ppDriverInfo)->cVersion = 3; + + // Finally copy the structure and advance to the next one in the output buffer. + *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo4Offsets, *ppDriverInfoEnd); + ToMultiSz((*ppDriverInfo)->pDependentFiles); + (*ppDriverInfo)++; +} + +static void +_LocalGetPrinterDriverLevel5(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_5W* ppDriverInfo, PBYTE* ppDriverInfoEnd, PDWORD pcbNeeded) +{ + DWORD n; + PCWSTR pwszStrings[5]; + + /* Clearly these things should not be hardcoded, so when it is needed, someone can add meaningfull values here */ + pwszStrings[0] = pHandle->pPrinter->pwszPrinterDriver; // pName + pwszStrings[1] = wszCurrentEnvironment; // pEnvironment + pwszStrings[2] = L"c:\\reactos\\system32\\localspl.dll"; // pDriverPath UniDrv.dll + pwszStrings[3] = L"c:\\reactos\\system32\\localspl.dll"; // pDataFile.ppd + pwszStrings[4] = L"c:\\reactos\\system32\\printui.dll"; // pConfigFile UniDrvUI.dll + + // Calculate the string lengths. + if (!ppDriverInfo) + { + for (n = 0; n < _countof(pwszStrings); ++n) + { + if (pwszStrings[n]) + { + *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR); + } + } + + *pcbNeeded += sizeof(DRIVER_INFO_5W); + return; + } + + (*ppDriverInfo)->cVersion = 3; + // Driver attributes, like UMPD/KMPD. + (*ppDriverInfo)->dwDriverAttributes = 0; // UMPD/KMPD, So where are they? + // Number of times the configuration file for this driver has been upgraded or downgraded since the last spooler restart. + (*ppDriverInfo)->dwConfigVersion = 1; + // Number of times the driver file for this driver has been upgraded or downgraded since the last spooler restart. + (*ppDriverInfo)->dwDriverVersion = 1; + + // Finally copy the structure and advance to the next one in the output buffer. + *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo5Offsets, *ppDriverInfoEnd); + (*ppDriverInfo)++; +} BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded) { @@ -168,8 +271,8 @@ BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Le pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle; - // Only support 3 levels for now - if (Level > 3) + // Only support 5 levels for now + if (Level > 5) { // The caller supplied an invalid level. dwErrorCode = ERROR_INVALID_LEVEL; @@ -185,6 +288,10 @@ BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Le _LocalGetPrinterDriverLevel2(pPrinterHandle, NULL, NULL, pcbNeeded); else if (Level == 3) _LocalGetPrinterDriverLevel3(pPrinterHandle, NULL, NULL, pcbNeeded); + else if (Level == 4) + _LocalGetPrinterDriverLevel4(pPrinterHandle, NULL, NULL, pcbNeeded); + else if (Level == 5) + _LocalGetPrinterDriverLevel5(pPrinterHandle, NULL, NULL, pcbNeeded); // Check if the supplied buffer is large enough. if (cbBuf < *pcbNeeded) @@ -202,6 +309,10 @@ BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Le _LocalGetPrinterDriverLevel2(pPrinterHandle, (PDRIVER_INFO_2W*)&pDriverInfo, &pEnd, NULL); else if (Level == 3) _LocalGetPrinterDriverLevel3(pPrinterHandle, (PDRIVER_INFO_3W*)&pDriverInfo, &pEnd, NULL); + else if (Level == 4) + _LocalGetPrinterDriverLevel4(pPrinterHandle, (PDRIVER_INFO_4W*)&pDriverInfo, &pEnd, NULL); + else if (Level == 5) + _LocalGetPrinterDriverLevel5(pPrinterHandle, (PDRIVER_INFO_5W*)&pDriverInfo, &pEnd, NULL); dwErrorCode = ERROR_SUCCESS;