reactos/win32ss/printing/base/spoolsv/printerdrivers.c
James Tabor 62c4b828b4 [Printing] Update and Add Functions
More forwards to LocalSpl and LocalMon. At sometime will be merged together.
Bug fixes.
Printer Driver code is a wine hack. (WIP)
Added information for shell tray icon notifications.
Sync wine WinSpool driver tests. Unplugged from build.
2020-08-26 17:12:20 -05:00

468 lines
15 KiB
C

/*
* PROJECT: ReactOS Print Spooler Service
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Functions related to Printer Drivers
* COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
*/
#include "precomp.h"
#include "marshalling/printerdrivers.h"
DWORD
_RpcAddPrinterDriver(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer)
{
DWORD dwErrorCode;
PBYTE pDriverInfo = NULL;
switch ( pDriverContainer->Level )
{
case 8:
{
WINSPOOL_DRIVER_INFO_8 *pdi = pDriverContainer->DriverInfo.Level8;
PDRIVER_INFO_8W pdi8w = DllAllocSplMem(sizeof(DRIVER_INFO_8W));
pDriverInfo = (PBYTE)pdi8w;
pdi8w->pszPrintProcessor = pdi->pPrintProcessor;
pdi8w->pszVendorSetup = pdi->pVendorSetup;
pdi8w->pszzColorProfiles = pdi->pszzColorProfiles;
pdi8w->pszInfPath = pdi->pInfPath;
pdi8w->pszzCoreDriverDependencies = pdi->pszzCoreDriverDependencies;
pdi8w->ftMinInboxDriverVerDate = pdi->ftMinInboxDriverVerDate;
pdi8w->dwlMinInboxDriverVerVersion = pdi->dwlMinInboxDriverVerVersion;
}
case 6:
{
WINSPOOL_DRIVER_INFO_6 *pdi = pDriverContainer->DriverInfo.Level6;
PDRIVER_INFO_6W pdi6w;
if ( pDriverInfo == NULL )
{
pdi6w = DllAllocSplMem(sizeof(DRIVER_INFO_6W));
pDriverInfo = (PBYTE)pdi6w;
}
else
{
pdi6w = (PDRIVER_INFO_6W)pDriverInfo;
}
pdi6w->pszMfgName = pdi->pMfgName;
pdi6w->pszOEMUrl = pdi->pOEMUrl;
pdi6w->pszHardwareID = pdi->pHardwareID;
pdi6w->pszProvider = pdi->pProvider;
pdi6w->ftDriverDate = pdi->ftDriverDate;
pdi6w->dwlDriverVersion = pdi->dwlDriverVersion;
}
case 4:
{
WINSPOOL_DRIVER_INFO_4 *pdi = pDriverContainer->DriverInfo.Level4;
PDRIVER_INFO_4W pdi4w;
if ( pDriverInfo == NULL )
{
pdi4w = DllAllocSplMem(sizeof(DRIVER_INFO_4W));
pDriverInfo = (PBYTE)pdi4w;
}
else
{
pdi4w = (PDRIVER_INFO_4W)pDriverInfo;
}
pdi4w->pszzPreviousNames = pdi->pszzPreviousNames;
}
case 3:
{
WINSPOOL_DRIVER_INFO_3 *pdi = pDriverContainer->DriverInfo.Level3;
PDRIVER_INFO_3W pdi3w;
if ( pDriverInfo == NULL )
{
pdi3w = DllAllocSplMem(sizeof(DRIVER_INFO_3W));
pDriverInfo = (PBYTE)pdi3w;
}
else
{
pdi3w = (PDRIVER_INFO_3W)pDriverInfo;
}
pdi3w->pHelpFile = pdi->pHelpFile;
pdi3w->pDependentFiles = pdi->pDependentFiles;
pdi3w->pMonitorName = pdi->pMonitorName;
pdi3w->pDefaultDataType = pdi->pDefaultDataType;
pdi3w->pDependentFiles = pdi->pDependentFiles;
}
case 2:
{
WINSPOOL_DRIVER_INFO_2 *pdi = pDriverContainer->DriverInfo.Level2;
PDRIVER_INFO_2W pdi2w;
if ( pDriverInfo == NULL )
{
pdi2w = DllAllocSplMem(sizeof(DRIVER_INFO_2W));
pDriverInfo = (PBYTE)pdi2w;
}
else
{
pdi2w = (PDRIVER_INFO_2W)pDriverInfo;
}
pdi2w->pName = pdi->pName;
pdi2w->pEnvironment = pdi->pEnvironment;
pdi2w->pDriverPath = pdi->pDriverPath;
pdi2w->pDataFile = pdi->pDataFile;
pdi2w->pConfigFile = pdi->pConfigFile;
}
break;
//
// At this point pDriverInfo is null.
//
default:
return ERROR_INVALID_LEVEL;
}
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!AddPrinterDriverW( pName, pDriverContainer->Level, pDriverInfo ))
dwErrorCode = GetLastError();
if ( pDriverInfo ) DllFreeSplMem( pDriverInfo );
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcAddPrinterDriverEx(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer, DWORD dwFileCopyFlags)
{
DWORD dwErrorCode;
PBYTE pDriverInfo = NULL;
switch ( pDriverContainer->Level )
{
case 8:
{
WINSPOOL_DRIVER_INFO_8 *pdi = pDriverContainer->DriverInfo.Level8;
PDRIVER_INFO_8W pdi8w = DllAllocSplMem(sizeof(DRIVER_INFO_8W));
pDriverInfo = (PBYTE)pdi8w;
pdi8w->pszPrintProcessor = pdi->pPrintProcessor;
pdi8w->pszVendorSetup = pdi->pVendorSetup;
pdi8w->pszzColorProfiles = pdi->pszzColorProfiles;
pdi8w->pszInfPath = pdi->pInfPath;
pdi8w->pszzCoreDriverDependencies = pdi->pszzCoreDriverDependencies;
pdi8w->ftMinInboxDriverVerDate = pdi->ftMinInboxDriverVerDate;
pdi8w->dwlMinInboxDriverVerVersion = pdi->dwlMinInboxDriverVerVersion;
}
case 6:
{
WINSPOOL_DRIVER_INFO_6 *pdi = pDriverContainer->DriverInfo.Level6;
PDRIVER_INFO_6W pdi6w;
if ( pDriverInfo == NULL )
{
pdi6w = DllAllocSplMem(sizeof(DRIVER_INFO_6W));
pDriverInfo = (PBYTE)pdi6w;
}
else
{
pdi6w = (PDRIVER_INFO_6W)pDriverInfo;
}
pdi6w->pszMfgName = pdi->pMfgName;
pdi6w->pszOEMUrl = pdi->pOEMUrl;
pdi6w->pszHardwareID = pdi->pHardwareID;
pdi6w->pszProvider = pdi->pProvider;
pdi6w->ftDriverDate = pdi->ftDriverDate;
pdi6w->dwlDriverVersion = pdi->dwlDriverVersion;
}
case 4:
{
WINSPOOL_DRIVER_INFO_4 *pdi = pDriverContainer->DriverInfo.Level4;
PDRIVER_INFO_4W pdi4w;
if ( pDriverInfo == NULL )
{
pdi4w = DllAllocSplMem(sizeof(DRIVER_INFO_4W));
pDriverInfo = (PBYTE)pdi4w;
}
else
{
pdi4w = (PDRIVER_INFO_4W)pDriverInfo;
}
pdi4w->pszzPreviousNames = pdi->pszzPreviousNames;
}
case 3:
{
WINSPOOL_DRIVER_INFO_3 *pdi = pDriverContainer->DriverInfo.Level3;
PDRIVER_INFO_3W pdi3w;
if ( pDriverInfo == NULL )
{
pdi3w = DllAllocSplMem(sizeof(DRIVER_INFO_3W));
pDriverInfo = (PBYTE)pdi3w;
}
else
{
pdi3w = (PDRIVER_INFO_3W)pDriverInfo;
}
pdi3w->pHelpFile = pdi->pHelpFile;
pdi3w->pDependentFiles = pdi->pDependentFiles;
pdi3w->pMonitorName = pdi->pMonitorName;
pdi3w->pDefaultDataType = pdi->pDefaultDataType;
pdi3w->pDependentFiles = pdi->pDependentFiles;
}
case 2:
{
WINSPOOL_DRIVER_INFO_2 *pdi = pDriverContainer->DriverInfo.Level2;
PDRIVER_INFO_2W pdi2w;
if ( pDriverInfo == NULL )
{
pdi2w = DllAllocSplMem(sizeof(DRIVER_INFO_2W));
pDriverInfo = (PBYTE)pdi2w;
}
else
{
pdi2w = (PDRIVER_INFO_2W)pDriverInfo;
}
pdi2w->pName = pdi->pName;
pdi2w->pEnvironment = pdi->pEnvironment;
pdi2w->pDriverPath = pdi->pDriverPath;
pdi2w->pDataFile = pdi->pDataFile;
pdi2w->pConfigFile = pdi->pConfigFile;
}
break;
//
// At this point pDriverInfo is null.
//
default:
return ERROR_INVALID_LEVEL;
}
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!AddPrinterDriverExW( pName, pDriverContainer->Level, pDriverInfo, dwFileCopyFlags ))
dwErrorCode = GetLastError();
if ( pDriverInfo ) DllFreeSplMem( pDriverInfo );
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcDeletePrinterDriver(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* pDriverName)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!DeletePrinterDriverW(pName, pEnvironment, pDriverName))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcDeletePrinterDriverEx(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* pDriverName, DWORD dwDeleteFlag, DWORD dwVersionNum)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!DeletePrinterDriverExW(pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionNum))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcEnumPrinterDrivers(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level, BYTE* pDrivers, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
{
DWORD dwErrorCode;
PBYTE pPrinterDriversEnumAligned;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
pPrinterDriversEnumAligned = AlignRpcPtr(pDrivers, &cbBuf);
if (EnumPrinterDriversW(pName, pEnvironment, Level, pPrinterDriversEnumAligned, cbBuf, pcbNeeded, pcReturned))
{
// Replace absolute pointer addresses in the output by relative offsets.
ASSERT(Level <= 6 || Level == 8);
MarshallDownStructuresArray(pPrinterDriversEnumAligned, *pcReturned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
}
else
{
dwErrorCode = GetLastError();
}
RpcRevertToSelf();
UndoAlignRpcPtr(pDrivers, pPrinterDriversEnumAligned, cbBuf, pcbNeeded);
return dwErrorCode;
}
DWORD
_RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded)
{
DWORD dwErrorCode;
PBYTE pDriverAligned;
TRACE("_RpcGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded);
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 <= 6 || Level == 8);
MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
}
else
{
dwErrorCode = GetLastError();
}
RpcRevertToSelf();
UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
return dwErrorCode;
}
BOOL WINAPI YGetPrinterDriver2(
HANDLE hPrinter,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pDriver,
DWORD cbBuf,
LPDWORD pcbNeeded,
DWORD dwClientMajorVersion,
DWORD dwClientMinorVersion,
PDWORD pdwServerMajorVersion,
PDWORD pdwServerMinorVersion,
BOOL bRPC ) // Seems that all Y fuctions have this.
{
DWORD dwErrorCode;
PBYTE pDriverAligned;
FIXME("_Rpc(Y)GetPrinterDriver2(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion);
if ( bRPC )
{
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
}
pDriverAligned = AlignRpcPtr(pDriver, &cbBuf);
if (GetPrinterDriverExW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion))
{
// Replace relative offset addresses in the output by absolute pointers.
ASSERT(Level <= 6 || Level == 8);
MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
}
else
{
dwErrorCode = GetLastError();
}
if ( bRPC ) RpcRevertToSelf();
UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
return dwErrorCode;
}
DWORD
_RpcGetPrinterDriver2(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded, DWORD dwClientMajorVersion, DWORD dwClientMinorVersion, DWORD* pdwServerMaxVersion, DWORD* pdwServerMinVersion)
{
DWORD dwErrorCode;
PBYTE pDriverAligned;
FIXME("_RpcGetPrinterDriver2(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMaxVersion, pdwServerMinVersion);
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
pDriverAligned = AlignRpcPtr(pDriver, &cbBuf);
if (GetPrinterDriverExW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMaxVersion, pdwServerMinVersion))
{
// Replace relative offset addresses in the output by absolute pointers.
ASSERT(Level <= 6 || Level == 8);
MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
}
else
{
dwErrorCode = GetLastError();
}
RpcRevertToSelf();
UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
return dwErrorCode;
}
DWORD
_RpcGetPrinterDriverDirectory(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level, BYTE* pDriverDirectory, DWORD cbBuf, DWORD* pcbNeeded)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!GetPrinterDriverDirectoryW(pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}