mirror of
https://github.com/reactos/reactos.git
synced 2024-08-26 13:18:51 +00:00
![James Tabor](/assets/img/avatar_default.png)
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.
468 lines
15 KiB
C
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;
|
|
}
|