mirror of
https://github.com/reactos/reactos.git
synced 2024-06-26 07:51:52 +00:00
[PRINTING] Semi-implement GetPrinterDriverW
CORE-15522
This commit is contained in:
parent
2e4457f223
commit
796dd5f53c
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include "marshalling/printerdrivers.h"
|
||||
|
||||
DWORD
|
||||
_RpcAddPrinterDriver(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer)
|
||||
|
@ -45,8 +46,33 @@ _RpcEnumPrinterDrivers(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level,
|
|||
DWORD
|
||||
_RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
DWORD dwErrorCode;
|
||||
PBYTE pDriverAligned;
|
||||
|
||||
dwErrorCode = RpcImpersonateClient(NULL);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
pDriverAligned = AlignRpcPtr(pDriver, &cbBuf);
|
||||
|
||||
if (GetPrinterDriverW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded))
|
||||
{
|
||||
// Replace relative offset addresses in the output by absolute pointers.
|
||||
ASSERT(Level >= 1 && Level <= 3);
|
||||
MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwErrorCode = GetLastError();
|
||||
}
|
||||
|
||||
RpcRevertToSelf();
|
||||
UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
|
||||
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "precomp.h"
|
||||
#include <marshalling/printers.h>
|
||||
#include <marshalling/printerdrivers.h>
|
||||
|
||||
// Local Constants
|
||||
|
||||
|
@ -513,8 +514,50 @@ GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriv
|
|||
BOOL WINAPI
|
||||
GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
|
||||
|
||||
TRACE("GetPrinterDriverW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
|
||||
return FALSE;
|
||||
|
||||
// Sanity checks.
|
||||
if (!pHandle)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Dismiss invalid levels already at this point.
|
||||
if (Level > 8 || Level < 1)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (cbBuf && pDriverInfo)
|
||||
ZeroMemory(pDriverInfo, cbBuf);
|
||||
|
||||
// Do the RPC call
|
||||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcGetPrinterDriver(pHandle->hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
dwErrorCode = RpcExceptionCode();
|
||||
ERR("_RpcGetPrinter failed with exception code %lu!\n", dwErrorCode);
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
if (dwErrorCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Replace relative offset addresses in the output by absolute pointers.
|
||||
ASSERT(Level <= 3);
|
||||
MarshallUpStructure(cbBuf, pDriverInfo, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
|
|
51
win32ss/printing/include/marshalling/printerdrivers.h
Normal file
51
win32ss/printing/include/marshalling/printerdrivers.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Printing Stack Marshalling Functions
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Marshalling definitions for DRIVER_INFO_*
|
||||
* COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
|
||||
*/
|
||||
|
||||
static const MARSHALLING PrinterDriver1Marshalling = {
|
||||
sizeof(DRIVER_INFO_1W),
|
||||
{
|
||||
{ FIELD_OFFSET(DRIVER_INFO_1W, pName), RTL_FIELD_SIZE(DRIVER_INFO_1W, pName), RTL_FIELD_SIZE(DRIVER_INFO_1W, pName), TRUE },
|
||||
{ MAXDWORD, 0, 0, FALSE }
|
||||
}
|
||||
};
|
||||
|
||||
static const MARSHALLING PrinterDriver2Marshalling = {
|
||||
sizeof(DRIVER_INFO_2W),
|
||||
{
|
||||
{ FIELD_OFFSET(DRIVER_INFO_2W, pName), RTL_FIELD_SIZE(DRIVER_INFO_2W, pName), RTL_FIELD_SIZE(DRIVER_INFO_2W, pName), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_2W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_2W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_2W, pEnvironment), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_2W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_2W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_2W, pDriverPath), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_2W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_2W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_2W, pDataFile), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_2W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_2W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_2W, pConfigFile), TRUE },
|
||||
{ MAXDWORD, 0, 0, FALSE }
|
||||
}
|
||||
};
|
||||
|
||||
static const MARSHALLING PrinterDriver3Marshalling = {
|
||||
sizeof(DRIVER_INFO_3W),
|
||||
{
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pName), RTL_FIELD_SIZE(DRIVER_INFO_3W, pName), RTL_FIELD_SIZE(DRIVER_INFO_3W, pName), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_3W, pEnvironment), RTL_FIELD_SIZE(DRIVER_INFO_3W, pEnvironment), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDriverPath), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDriverPath), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDataFile), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDataFile), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_3W, pConfigFile), RTL_FIELD_SIZE(DRIVER_INFO_3W, pConfigFile), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pHelpFile), RTL_FIELD_SIZE(DRIVER_INFO_3W, pHelpFile), RTL_FIELD_SIZE(DRIVER_INFO_3W, pHelpFile), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pDependentFiles), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDependentFiles), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDependentFiles), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pMonitorName), RTL_FIELD_SIZE(DRIVER_INFO_3W, pMonitorName), RTL_FIELD_SIZE(DRIVER_INFO_3W, pMonitorName), TRUE },
|
||||
{ FIELD_OFFSET(DRIVER_INFO_3W, pDefaultDataType), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDefaultDataType), RTL_FIELD_SIZE(DRIVER_INFO_3W, pDefaultDataType), TRUE },
|
||||
{ MAXDWORD, 0, 0, FALSE }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const MARSHALLING* pPrinterDriverMarshalling[] = {
|
||||
NULL,
|
||||
&PrinterDriver1Marshalling,
|
||||
&PrinterDriver2Marshalling,
|
||||
&PrinterDriver3Marshalling,
|
||||
};
|
|
@ -10,6 +10,7 @@ list(APPEND SOURCE
|
|||
ports.c
|
||||
precomp.h
|
||||
printerdata.c
|
||||
printerdrivers.c
|
||||
printers.c
|
||||
printingthread.c
|
||||
printprocessors.c
|
||||
|
|
|
@ -43,7 +43,7 @@ static const PRINTPROVIDOR _PrintProviderFunctions = {
|
|||
LocalEnumPrinters, // fpEnumPrinters
|
||||
NULL, // fpAddPrinterDriver
|
||||
NULL, // fpEnumPrinterDrivers
|
||||
NULL, // fpGetPrinterDriver
|
||||
LocalGetPrinterDriver, // fpGetPrinterDriver
|
||||
NULL, // fpGetPrinterDriverDirectory
|
||||
NULL, // fpDeletePrinterDriver
|
||||
NULL, // fpAddPrintProcessor
|
||||
|
|
|
@ -287,6 +287,10 @@ DWORD WINAPI LocalGetPrinterDataEx(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pVal
|
|||
DWORD WINAPI LocalSetPrinterData(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData);
|
||||
DWORD WINAPI LocalSetPrinterDataEx(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData);
|
||||
|
||||
// printerdriver.c
|
||||
BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded);
|
||||
|
||||
|
||||
// printers.c
|
||||
extern SKIPLIST PrinterList;
|
||||
BOOL InitializePrinterList(void);
|
||||
|
|
211
win32ss/printing/providers/localspl/printerdrivers.c
Normal file
211
win32ss/printing/providers/localspl/printerdrivers.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Local Spooler
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Functions for printer driver information
|
||||
* COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
|
||||
// Local Constants
|
||||
static DWORD dwDriverInfo1Offsets[] = {
|
||||
FIELD_OFFSET(DRIVER_INFO_1W, pName),
|
||||
MAXDWORD
|
||||
};
|
||||
|
||||
static DWORD dwDriverInfo2Offsets[] = {
|
||||
FIELD_OFFSET(DRIVER_INFO_2W, pName),
|
||||
FIELD_OFFSET(DRIVER_INFO_2W, pEnvironment),
|
||||
FIELD_OFFSET(DRIVER_INFO_2W, pDriverPath),
|
||||
FIELD_OFFSET(DRIVER_INFO_2W, pDataFile),
|
||||
FIELD_OFFSET(DRIVER_INFO_2W, pConfigFile),
|
||||
MAXDWORD
|
||||
};
|
||||
|
||||
static DWORD dwDriverInfo3Offsets[] = {
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pName),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pEnvironment),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pDriverPath),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pDataFile),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pConfigFile),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pHelpFile),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pDependentFiles),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pMonitorName),
|
||||
FIELD_OFFSET(DRIVER_INFO_3W, pDefaultDataType),
|
||||
MAXDWORD
|
||||
};
|
||||
|
||||
static void
|
||||
ToMultiSz(LPWSTR pString)
|
||||
{
|
||||
while (*pString)
|
||||
{
|
||||
if (*pString == '|')
|
||||
*pString = '\0';
|
||||
pString++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_LocalGetPrinterDriverLevel1(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_1W* ppDriverInfo, PBYTE* ppDriverInfoEnd, PDWORD pcbNeeded)
|
||||
{
|
||||
DWORD n;
|
||||
PCWSTR pwszStrings[1];
|
||||
|
||||
/* This value is only here to send something, I have not verified if it is actually correct */
|
||||
pwszStrings[0] = pHandle->pPrinter->pwszPrinterDriver;
|
||||
|
||||
// Calculate the string lengths.
|
||||
if (!ppDriverInfo)
|
||||
{
|
||||
for (n = 0; n < _countof(pwszStrings); ++n)
|
||||
{
|
||||
*pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
*pcbNeeded += sizeof(DRIVER_INFO_1W);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Finally copy the structure and advance to the next one in the output buffer.
|
||||
*ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo1Offsets, *ppDriverInfoEnd);
|
||||
(*ppDriverInfo)++;
|
||||
}
|
||||
|
||||
static void
|
||||
_LocalGetPrinterDriverLevel2(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_2W* 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
|
||||
pwszStrings[3] = L"c:\\reactos\\system32\\localspl.dll"; // pDataFile
|
||||
pwszStrings[4] = L"c:\\reactos\\system32\\localspl.dll"; // pConfigFile
|
||||
|
||||
// Calculate the string lengths.
|
||||
if (!ppDriverInfo)
|
||||
{
|
||||
for (n = 0; n < _countof(pwszStrings); ++n)
|
||||
{
|
||||
*pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
*pcbNeeded += sizeof(DRIVER_INFO_2W);
|
||||
return;
|
||||
}
|
||||
|
||||
(*ppDriverInfo)->cVersion = 3;
|
||||
|
||||
// Finally copy the structure and advance to the next one in the output buffer.
|
||||
*ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo2Offsets, *ppDriverInfoEnd);
|
||||
(*ppDriverInfo)++;
|
||||
}
|
||||
|
||||
static void
|
||||
_LocalGetPrinterDriverLevel3(PLOCAL_PRINTER_HANDLE pHandle, PDRIVER_INFO_3W* ppDriverInfo, PBYTE* ppDriverInfoEnd, PDWORD pcbNeeded)
|
||||
{
|
||||
DWORD n;
|
||||
PCWSTR pwszStrings[9];
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
// 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_3W);
|
||||
return;
|
||||
}
|
||||
|
||||
(*ppDriverInfo)->cVersion = 3;
|
||||
|
||||
// Finally copy the structure and advance to the next one in the output buffer.
|
||||
*ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo3Offsets, *ppDriverInfoEnd);
|
||||
ToMultiSz((*ppDriverInfo)->pDependentFiles);
|
||||
(*ppDriverInfo)++;
|
||||
}
|
||||
|
||||
|
||||
BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
PBYTE pEnd = &pDriverInfo[cbBuf];
|
||||
PLOCAL_HANDLE pHandle;
|
||||
PLOCAL_PRINTER_HANDLE pPrinterHandle;
|
||||
|
||||
TRACE("LocalGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
|
||||
|
||||
// Check if this is a printer handle.
|
||||
pHandle = (PLOCAL_HANDLE)hPrinter;
|
||||
if (pHandle->HandleType != HandleType_Printer)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
|
||||
|
||||
// Only support 3 levels for now
|
||||
if (Level > 3)
|
||||
{
|
||||
// The caller supplied an invalid level.
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Count the required buffer size.
|
||||
*pcbNeeded = 0;
|
||||
|
||||
if (Level == 1)
|
||||
_LocalGetPrinterDriverLevel1(pPrinterHandle, NULL, NULL, pcbNeeded);
|
||||
else if (Level == 2)
|
||||
_LocalGetPrinterDriverLevel2(pPrinterHandle, NULL, NULL, pcbNeeded);
|
||||
else if (Level == 3)
|
||||
_LocalGetPrinterDriverLevel3(pPrinterHandle, NULL, NULL, pcbNeeded);
|
||||
|
||||
// Check if the supplied buffer is large enough.
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Copy over the information.
|
||||
pEnd = &pDriverInfo[*pcbNeeded];
|
||||
|
||||
if (Level == 1)
|
||||
_LocalGetPrinterDriverLevel1(pPrinterHandle, (PDRIVER_INFO_1W*)&pDriverInfo, &pEnd, NULL);
|
||||
else if (Level == 2)
|
||||
_LocalGetPrinterDriverLevel2(pPrinterHandle, (PDRIVER_INFO_2W*)&pDriverInfo, &pEnd, NULL);
|
||||
else if (Level == 3)
|
||||
_LocalGetPrinterDriverLevel3(pPrinterHandle, (PDRIVER_INFO_3W*)&pDriverInfo, &pEnd, NULL);
|
||||
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
Loading…
Reference in a new issue