[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.
This commit is contained in:
James Tabor 2020-01-31 17:38:47 -06:00
parent 45f39ffc25
commit adffa8ea75
6 changed files with 169 additions and 9 deletions

View file

@ -49,6 +49,8 @@ _RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWOR
DWORD dwErrorCode; DWORD dwErrorCode;
PBYTE pDriverAligned; PBYTE pDriverAligned;
ERR("_RpcGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded);
dwErrorCode = RpcImpersonateClient(NULL); dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS) if (dwErrorCode != ERROR_SUCCESS)
{ {
@ -61,7 +63,7 @@ _RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWOR
if (GetPrinterDriverW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded)) if (GetPrinterDriverW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded))
{ {
// Replace relative offset addresses in the output by absolute pointers. // 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); MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
} }
else else

View file

@ -15,6 +15,7 @@
#include <winreg.h> #include <winreg.h>
#include <winspool.h> #include <winspool.h>
#include <winspool_c.h> #include <winspool_c.h>
#include <winddiui.h>
#include <ndk/rtlfuncs.h> #include <ndk/rtlfuncs.h>
#include <spoolss.h> #include <spoolss.h>

View file

@ -194,6 +194,14 @@ DeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort, WORD fwCapability, LPWSTR pO
return 0; 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 LONG WINAPI
DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput, DWORD fMode) 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; DWORD dwErrorCode;
PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; 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. // Sanity checks.
if (!pHandle) if (!pHandle)
@ -1076,7 +1084,7 @@ GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDri
if (dwErrorCode == ERROR_SUCCESS) if (dwErrorCode == ERROR_SUCCESS)
{ {
// Replace relative offset addresses in the output by absolute pointers. // 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); 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; return FALSE;
} }
BOOL WINAPI
SplDriverUnloadComplete(LPWSTR pDriverFile)
{
ERR("DriverUnloadComplete(%S)\n", pDriverFile);
UNIMPLEMENTED;
return TRUE; // return true for now.
}
DWORD WINAPI DWORD WINAPI
StartDocPrinterA(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo) StartDocPrinterA(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo)
{ {

View file

@ -74,7 +74,7 @@
173 stdcall DeviceCapabilitiesW(wstr wstr long ptr ptr) 173 stdcall DeviceCapabilitiesW(wstr wstr long ptr ptr)
174 stub DeviceMode 174 stub DeviceMode
175 stub DevicePropertySheets 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) 177 stdcall DocumentPropertiesA(ptr ptr ptr ptr ptr long)
178 stdcall DocumentPropertiesW(ptr ptr ptr ptr ptr long) 178 stdcall DocumentPropertiesW(ptr ptr ptr ptr ptr long)
179 stub DocumentPropertySheets 179 stub DocumentPropertySheets
@ -186,7 +186,7 @@
285 stdcall SetPrinterDataExW(ptr wstr wstr long ptr long) 285 stdcall SetPrinterDataExW(ptr wstr wstr long ptr long)
286 stdcall SetPrinterDataW(ptr wstr long ptr long) 286 stdcall SetPrinterDataW(ptr wstr long ptr long)
287 stdcall SetPrinterW(ptr long ptr long) 287 stdcall SetPrinterW(ptr long ptr long)
288 stub SplDriverUnloadComplete 288 stdcall SplDriverUnloadComplete(ptr)
289 stub SpoolerDevQueryPrintW 289 stub SpoolerDevQueryPrintW
290 stdcall SpoolerInit() 290 stdcall SpoolerInit()
291 stub SpoolerPrinterEvent 291 stub SpoolerPrinterEvent

View 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[] = { static const MARSHALLING* pPrinterDriverMarshalling[] = {
@ -48,4 +76,6 @@ static const MARSHALLING* pPrinterDriverMarshalling[] = {
&PrinterDriver1Marshalling, &PrinterDriver1Marshalling,
&PrinterDriver2Marshalling, &PrinterDriver2Marshalling,
&PrinterDriver3Marshalling, &PrinterDriver3Marshalling,
&PrinterDriver4Marshalling,
&PrinterDriver5Marshalling,
}; };

View file

@ -7,7 +7,6 @@
#include "precomp.h" #include "precomp.h"
// Local Constants // Local Constants
static DWORD dwDriverInfo1Offsets[] = { static DWORD dwDriverInfo1Offsets[] = {
FIELD_OFFSET(DRIVER_INFO_1W, pName), FIELD_OFFSET(DRIVER_INFO_1W, pName),
@ -36,6 +35,29 @@ static DWORD dwDriverInfo3Offsets[] = {
MAXDWORD 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 static void
ToMultiSz(LPWSTR pString) ToMultiSz(LPWSTR pString)
{ {
@ -148,6 +170,87 @@ _LocalGetPrinterDriverLevel3(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_3W* ppD
(*ppDriverInfo)++; (*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) 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; pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
// Only support 3 levels for now // Only support 5 levels for now
if (Level > 3) if (Level > 5)
{ {
// The caller supplied an invalid level. // The caller supplied an invalid level.
dwErrorCode = ERROR_INVALID_LEVEL; dwErrorCode = ERROR_INVALID_LEVEL;
@ -185,6 +288,10 @@ BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Le
_LocalGetPrinterDriverLevel2(pPrinterHandle, NULL, NULL, pcbNeeded); _LocalGetPrinterDriverLevel2(pPrinterHandle, NULL, NULL, pcbNeeded);
else if (Level == 3) else if (Level == 3)
_LocalGetPrinterDriverLevel3(pPrinterHandle, NULL, NULL, pcbNeeded); _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. // Check if the supplied buffer is large enough.
if (cbBuf < *pcbNeeded) if (cbBuf < *pcbNeeded)
@ -202,6 +309,10 @@ BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Le
_LocalGetPrinterDriverLevel2(pPrinterHandle, (PDRIVER_INFO_2W*)&pDriverInfo, &pEnd, NULL); _LocalGetPrinterDriverLevel2(pPrinterHandle, (PDRIVER_INFO_2W*)&pDriverInfo, &pEnd, NULL);
else if (Level == 3) else if (Level == 3)
_LocalGetPrinterDriverLevel3(pPrinterHandle, (PDRIVER_INFO_3W*)&pDriverInfo, &pEnd, NULL); _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; dwErrorCode = ERROR_SUCCESS;