[Printing] Part of GDI Support
authorJames Tabor <james.tabor@reactos.org>
Fri, 31 Jan 2020 23:38:47 +0000 (17:38 -0600)
committerJames Tabor <james.tabor@reactos.org>
Fri, 31 Jan 2020 23:38:47 +0000 (17:38 -0600)
Fix ups and added support to prevent GDI from crashing. These functions
will be required for GDI.

Part 1 of print support.

win32ss/printing/base/spoolsv/printerdrivers.c
win32ss/printing/base/winspool/precomp.h
win32ss/printing/base/winspool/printers.c
win32ss/printing/base/winspool/winspool.spec
win32ss/printing/include/marshalling/printerdrivers.h
win32ss/printing/providers/localspl/printerdrivers.c

index a1f4586..ae85f84 100644 (file)
@@ -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
index cbfaac9..033b38d 100644 (file)
@@ -15,6 +15,7 @@
 #include <winreg.h>
 #include <winspool.h>
 #include <winspool_c.h>
+#include <winddiui.h>
 #include <ndk/rtlfuncs.h>
 
 #include <spoolss.h>
index 7fd34a4..0e77294 100644 (file)
@@ -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)
 {
index 7c2888b..318a2df 100644 (file)
@@ -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
 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
index 49951bd..ffaf50f 100644 (file)
@@ -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,
 };
index 5bb5b3d..351667c 100644 (file)
@@ -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;