reactos/win32ss/printing/base/spoolsv/printers.c

411 lines
12 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Print Spooler Service
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Functions related to Printers and printing
* COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
*/
#include "precomp.h"
static void
_MarshallDownPrinterInfo(PBYTE* ppPrinterInfo, DWORD Level)
{
// Replace absolute pointer addresses in the output by relative offsets.
if (Level == 0)
{
PPRINTER_INFO_STRESS pPrinterInfo0 = (PPRINTER_INFO_STRESS)(*ppPrinterInfo);
pPrinterInfo0->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo0->pPrinterName - (ULONG_PTR)pPrinterInfo0);
if (pPrinterInfo0->pServerName)
pPrinterInfo0->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo0->pServerName - (ULONG_PTR)pPrinterInfo0);
*ppPrinterInfo += sizeof(PRINTER_INFO_STRESS);
}
else if (Level == 1)
{
PPRINTER_INFO_1W pPrinterInfo1 = (PPRINTER_INFO_1W)(*ppPrinterInfo);
pPrinterInfo1->pName = (PWSTR)((ULONG_PTR)pPrinterInfo1->pName - (ULONG_PTR)pPrinterInfo1);
pPrinterInfo1->pDescription = (PWSTR)((ULONG_PTR)pPrinterInfo1->pDescription - (ULONG_PTR)pPrinterInfo1);
pPrinterInfo1->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo1->pComment - (ULONG_PTR)pPrinterInfo1);
*ppPrinterInfo += sizeof(PRINTER_INFO_1W);
}
else if (Level == 2)
{
PPRINTER_INFO_2W pPrinterInfo2 = (PPRINTER_INFO_2W)(*ppPrinterInfo);
pPrinterInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPrinterName - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pShareName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pShareName - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPortName - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pDriverName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDriverName - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo2->pComment - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pLocation = (PWSTR)((ULONG_PTR)pPrinterInfo2->pLocation - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo2->pDevMode - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pSepFile = (PWSTR)((ULONG_PTR)pPrinterInfo2->pSepFile - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPrintProcessor - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pDatatype = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDatatype - (ULONG_PTR)pPrinterInfo2);
pPrinterInfo2->pParameters = (PWSTR)((ULONG_PTR)pPrinterInfo2->pParameters - (ULONG_PTR)pPrinterInfo2);
if (pPrinterInfo2->pServerName)
pPrinterInfo2->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pServerName - (ULONG_PTR)pPrinterInfo2);
if (pPrinterInfo2->pSecurityDescriptor)
pPrinterInfo2->pSecurityDescriptor = (PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo2->pSecurityDescriptor - (ULONG_PTR)pPrinterInfo2);
*ppPrinterInfo += sizeof(PRINTER_INFO_2W);
}
else if (Level == 3)
{
PPRINTER_INFO_3 pPrinterInfo3 = (PPRINTER_INFO_3)(*ppPrinterInfo);
pPrinterInfo3->pSecurityDescriptor = (PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo3->pSecurityDescriptor - (ULONG_PTR)pPrinterInfo3);
*ppPrinterInfo += sizeof(PRINTER_INFO_3);
}
else if (Level == 4)
{
PPRINTER_INFO_4W pPrinterInfo4 = (PPRINTER_INFO_4W)(*ppPrinterInfo);
pPrinterInfo4->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo4->pPrinterName - (ULONG_PTR)pPrinterInfo4);
if (pPrinterInfo4->pServerName)
pPrinterInfo4->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo4->pServerName - (ULONG_PTR)pPrinterInfo4);
*ppPrinterInfo += sizeof(PRINTER_INFO_4W);
}
else if (Level == 5)
{
PPRINTER_INFO_5W pPrinterInfo5 = (PPRINTER_INFO_5W)(*ppPrinterInfo);
pPrinterInfo5->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo5->pPrinterName - (ULONG_PTR)pPrinterInfo5);
pPrinterInfo5->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo5->pPortName - (ULONG_PTR)pPrinterInfo5);
*ppPrinterInfo += sizeof(PRINTER_INFO_5W);
}
else if (Level == 6)
{
*ppPrinterInfo += sizeof(PRINTER_INFO_6);
}
else if (Level == 7)
{
PPRINTER_INFO_7W pPrinterInfo7 = (PPRINTER_INFO_7W)(*ppPrinterInfo);
if (pPrinterInfo7->pszObjectGUID)
pPrinterInfo7->pszObjectGUID = (PWSTR)((ULONG_PTR)pPrinterInfo7->pszObjectGUID - (ULONG_PTR)pPrinterInfo7);
*ppPrinterInfo += sizeof(PRINTER_INFO_7W);
}
else if (Level == 8)
{
PPRINTER_INFO_8W pPrinterInfo8 = (PPRINTER_INFO_8W)(*ppPrinterInfo);
pPrinterInfo8->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo8->pDevMode - (ULONG_PTR)pPrinterInfo8);
*ppPrinterInfo += sizeof(PRINTER_INFO_8W);
}
else if (Level == 9)
{
PPRINTER_INFO_9W pPrinterInfo9 = (PPRINTER_INFO_9W)(*ppPrinterInfo);
pPrinterInfo9->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo9->pDevMode - (ULONG_PTR)pPrinterInfo9);
*ppPrinterInfo += sizeof(PRINTER_INFO_9W);
}
}
DWORD
_RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcAddPrinter(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_PRINTER_HANDLE* pHandle)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcAddPrinterEx(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo, WINSPOOL_PRINTER_HANDLE* pHandle)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcClosePrinter(WINSPOOL_PRINTER_HANDLE* phPrinter)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (ClosePrinter(*phPrinter))
*phPrinter = NULL;
else
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcDeletePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcEndDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!EndDocPrinter(hPrinter))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcEndPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!EndPagePrinter(hPrinter))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD Level, BYTE* pPrinterEnum, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
{
DWORD dwErrorCode;
PBYTE pPrinterEnumAligned;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
pPrinterEnumAligned = AlignRpcPtr(pPrinterEnum, &cbBuf);
if (EnumPrintersW(Flags, Name, Level, pPrinterEnumAligned, cbBuf, pcbNeeded, pcReturned))
{
DWORD i;
PBYTE p = pPrinterEnumAligned;
for (i = 0; i < *pcReturned; i++)
_MarshallDownPrinterInfo(&p, Level);
}
else
{
dwErrorCode = GetLastError();
}
RpcRevertToSelf();
UndoAlignRpcPtr(pPrinterEnum, pPrinterEnumAligned, cbBuf, pcbNeeded);
return dwErrorCode;
}
DWORD
_RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten, DWORD cSleep)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pPrinter, DWORD cbBuf, DWORD* pcbNeeded)
{
DWORD dwErrorCode;
PBYTE pPrinterAligned;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
pPrinterAligned = AlignRpcPtr(pPrinter, &cbBuf);
if (GetPrinterW(hPrinter, Level, pPrinterAligned, cbBuf, pcbNeeded))
{
PBYTE p = pPrinterAligned;
_MarshallDownPrinterInfo(&p, Level);
}
else
{
dwErrorCode = GetLastError();
}
RpcRevertToSelf();
UndoAlignRpcPtr(pPrinter, pPrinterAligned, cbBuf, pcbNeeded);
return dwErrorCode;
}
DWORD
_RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired)
{
DWORD dwErrorCode;
PRINTER_DEFAULTSW Default;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
Default.DesiredAccess = AccessRequired;
Default.pDatatype = pDatatype;
Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
if (!OpenPrinterW(pPrinterName, phPrinter, &Default))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* pHandle, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcNoBytesRead)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!ReadPrinter(hPrinter, pBuf, cbBuf, pcNoBytesRead))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcResetPrinterEx(VOID)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcSeekPrinter(VOID)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, DWORD Command)
{
UNIMPLEMENTED;
return ERROR_INVALID_FUNCTION;
}
DWORD
_RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_DOC_INFO_CONTAINER* pDocInfoContainer, DWORD* pJobId)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
*pJobId = StartDocPrinterW(hPrinter, pDocInfoContainer->Level, (PBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!StartPagePrinter(hPrinter))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}
DWORD
_RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten)
{
DWORD dwErrorCode;
dwErrorCode = RpcImpersonateClient(NULL);
if (dwErrorCode != ERROR_SUCCESS)
{
ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
return dwErrorCode;
}
if (!WritePrinter(hPrinter, pBuf, cbBuf, pcWritten))
dwErrorCode = GetLastError();
RpcRevertToSelf();
return dwErrorCode;
}