mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 13:34:53 +00:00
[0.4.13][PRINTING] Fix regression CORE-16622 in comdlg32:printdlg ANSI
A very nice set of patches done by Doug Lyons!, Jim Tabor, Colin Finck to fix: - a crash on the testbots for comdlg32:printdlg - erroneous behavior of PrintDlg in _A()-application "Kompozer", namely - prevents exceptions from being thrown when opening the print dlg - prevents heap allocations of 0 byte size when opening the print dlg - prevents a help-button that should be invisible from overlapping other controls - allows Kompozer to extend the print-dialog with additional controls - allows combobox to show the printers name, instead of memory garbage [PRINTING] Improve Stubs for GetPrinterA and GetPrinterDeviceA (#2274) cherry picked from commit 0.4.14-dev-849-gacec69a1d7
[WINSPOOL] Add Implementation of EnumPrintersA (#2273) cherry picked from commit 0.4.14-dev-878-ge8b177825b
[FORMATTING] Fix indentation of winspool/printers.c No code changes cherry picked from commit 0.4.14-dev-879-g45f39ffc25
[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. cherry picked from commit 0.4.14-dev-880-gadffa8ea75
[WINSPOOL] printers.c: Demote 3 ERR() to TRACE(), Fix 1 copypasta (#2311) cherry picked from commit 0.4.14-dev-889-g06f8f80181
[WINSPOOL] Implement GetPrinterDriverA and a helper function UnicodeToAnsiInPlace (#2317) cherry picked from commit 0.4.14-dev-957-gd90beaeed2
[WINSPOOL] Fix build cherry picked from commit 0.4.14-dev-958-g8da7fbc704
[GDI32] GdiConvertToDevmodeW: Import WINE commit 32393796bb534e9cf11dd988dce88722c67f7906 ("gdi32: GdiConvertToDevmodeW should not refer to unintialized name bytes.") This makes our GdiConvertToDevmodeW equivalent to the WINE counterpart again. cherry picked from commit 0.4.14-dev-1031-g5d8c39753e
[WINSPOOL] Implement DocumentPropertiesA including DEVMODE conversions (#2339) Co-authored-by: Doug Lyons <douglyons@douglyons.com> Co-authored-by: Colin Finck <colin@reactos.org> cherry picked from commit 0.4.14-dev-1035-g3077c0e43e
This commit is contained in:
parent
138d9acd79
commit
818e5bc752
|
@ -962,6 +962,7 @@ bMakePathNameW(LPWSTR lpBuffer,LPCWSTR lpFileName,LPWSTR *lpFilePart,DWORD unkno
|
|||
|
||||
/*
|
||||
* @implemented
|
||||
* Synchronized with WINE dlls/gdi32/driver.c
|
||||
*/
|
||||
DEVMODEW *
|
||||
WINAPI
|
||||
|
@ -986,15 +987,19 @@ GdiConvertToDevmodeW(const DEVMODEA *dmA)
|
|||
dmW = HeapAlloc(GetProcessHeap(), 0, dmW_size + dmA->dmDriverExtra);
|
||||
if (!dmW) return NULL;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmDeviceName, CCHDEVICENAME,
|
||||
dmW->dmDeviceName, CCHDEVICENAME);
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmDeviceName, -1,
|
||||
dmW->dmDeviceName, CCHDEVICENAME);
|
||||
/* copy slightly more, to avoid long computations */
|
||||
memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion, dmA_size - CCHDEVICENAME);
|
||||
|
||||
if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmFormName, CCHFORMNAME,
|
||||
dmW->dmFormName, CCHFORMNAME);
|
||||
if (dmA->dmFields & DM_FORMNAME)
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmFormName, -1,
|
||||
dmW->dmFormName, CCHFORMNAME);
|
||||
else
|
||||
dmW->dmFormName[0] = 0;
|
||||
|
||||
if (dmA_size > FIELD_OFFSET(DEVMODEA, dmLogPixels))
|
||||
memcpy(&dmW->dmLogPixels, &dmA->dmLogPixels, dmA_size - FIELD_OFFSET(DEVMODEA, dmLogPixels));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,6 +17,7 @@ list(APPEND SOURCE
|
|||
printers.c
|
||||
printprocessors.c
|
||||
printproviders.c
|
||||
utils.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/winspool_c.c)
|
||||
|
||||
add_library(winspool MODULE
|
||||
|
|
|
@ -233,3 +233,82 @@ Failure:
|
|||
SetLastError(ERROR_INVALID_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pDevModeOutput)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
/* this is the minimal dmSize that XP accepts */
|
||||
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 * 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;
|
||||
|
||||
// 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 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);
|
||||
|
||||
// Handle dmFormName if the input DEVMODEW is large enough to contain one.
|
||||
if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME * sizeof(WCHAR))
|
||||
{
|
||||
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 + dmA_size, (const char *)dmW + dmW_size, dmW->dmDriverExtra);
|
||||
|
||||
// Set the corrected dmSize and we are done.
|
||||
dmA->dmSize = dmA_size;
|
||||
|
||||
return dmA;
|
||||
}
|
||||
|
||||
void RosConvertUnicodeDevModeToAnsiDevmode(PDEVMODEW pDevModeInput, PDEVMODEA pDevModeOutput)
|
||||
{
|
||||
// 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 = _ConvertToDevmodeA(pDevModeInput);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#include <winreg.h>
|
||||
#include <winspool.h>
|
||||
#include <winspool_c.h>
|
||||
#include <winddiui.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#include <spoolss.h>
|
||||
#include <marshalling/marshalling.h>
|
||||
|
@ -39,4 +41,12 @@ SPOOLER_HANDLE, *PSPOOLER_HANDLE;
|
|||
// main.c
|
||||
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
|
||||
|
|
File diff suppressed because it is too large
Load diff
55
win32ss/printing/base/winspool/utils.c
Normal file
55
win32ss/printing/base/winspool/utils.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Spooler API
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Utility Functions related to Print Processors
|
||||
* COPYRIGHT: Copyright 2020 Doug Lyons (douglyons@douglyons.com)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
BOOL UnicodeToAnsiInPlace(PWSTR pwszField)
|
||||
{
|
||||
/*
|
||||
* This converts an incoming Unicode string to an ANSI string.
|
||||
* It returns FALSE on failure, otherwise it returns TRUE.
|
||||
* It is only useful for "in-place" conversions where the ANSI string goes
|
||||
* back into the same place where the Unicode string came into this function.
|
||||
* It seems that many of the functions involving printing can use this.
|
||||
*/
|
||||
|
||||
PSTR pszTemp;
|
||||
DWORD cch;
|
||||
|
||||
/*
|
||||
* Map the incoming Unicode pwszField string to an ANSI one here so that we can do
|
||||
* in-place conversion. We read the Unicode input and then we write back the ANSI
|
||||
* conversion into the same buffer for use with our GetPrinterDriverA function
|
||||
*/
|
||||
PSTR pszField = (PSTR)pwszField;
|
||||
|
||||
if (!pwszField)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cch = wcslen(pwszField);
|
||||
if (cch == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pszTemp = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
|
||||
if (!pszField)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
ERR("HeapAlloc failed!\n");
|
||||
return FALSE; // indicates a failure to be handled by caller
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, pwszField, -1, pszTemp, cch + 1, NULL, NULL);
|
||||
StringCchCopyA(pszField, cch + 1, pszTemp);
|
||||
|
||||
HeapFree(hProcessHeap, 0, pszTemp);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue