2 * PROJECT: ReactOS Print Spooler Service
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions related to Printers and printing
5 * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
11 _MarshallDownPrinterInfo(PBYTE
* ppPrinterInfo
, DWORD Level
)
13 // Replace absolute pointer addresses in the output by relative offsets.
16 PPRINTER_INFO_STRESS pPrinterInfo0
= (PPRINTER_INFO_STRESS
)(*ppPrinterInfo
);
18 pPrinterInfo0
->pPrinterName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo0
->pPrinterName
- (ULONG_PTR
)pPrinterInfo0
);
20 if (pPrinterInfo0
->pServerName
)
21 pPrinterInfo0
->pServerName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo0
->pServerName
- (ULONG_PTR
)pPrinterInfo0
);
23 *ppPrinterInfo
+= sizeof(PRINTER_INFO_STRESS
);
27 PPRINTER_INFO_1W pPrinterInfo1
= (PPRINTER_INFO_1W
)(*ppPrinterInfo
);
29 pPrinterInfo1
->pName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo1
->pName
- (ULONG_PTR
)pPrinterInfo1
);
30 pPrinterInfo1
->pDescription
= (PWSTR
)((ULONG_PTR
)pPrinterInfo1
->pDescription
- (ULONG_PTR
)pPrinterInfo1
);
31 pPrinterInfo1
->pComment
= (PWSTR
)((ULONG_PTR
)pPrinterInfo1
->pComment
- (ULONG_PTR
)pPrinterInfo1
);
33 *ppPrinterInfo
+= sizeof(PRINTER_INFO_1W
);
37 PPRINTER_INFO_2W pPrinterInfo2
= (PPRINTER_INFO_2W
)(*ppPrinterInfo
);
39 pPrinterInfo2
->pPrinterName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pPrinterName
- (ULONG_PTR
)pPrinterInfo2
);
40 pPrinterInfo2
->pShareName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pShareName
- (ULONG_PTR
)pPrinterInfo2
);
41 pPrinterInfo2
->pPortName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pPortName
- (ULONG_PTR
)pPrinterInfo2
);
42 pPrinterInfo2
->pDriverName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pDriverName
- (ULONG_PTR
)pPrinterInfo2
);
43 pPrinterInfo2
->pComment
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pComment
- (ULONG_PTR
)pPrinterInfo2
);
44 pPrinterInfo2
->pLocation
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pLocation
- (ULONG_PTR
)pPrinterInfo2
);
45 pPrinterInfo2
->pDevMode
= (PDEVMODEW
)((ULONG_PTR
)pPrinterInfo2
->pDevMode
- (ULONG_PTR
)pPrinterInfo2
);
46 pPrinterInfo2
->pSepFile
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pSepFile
- (ULONG_PTR
)pPrinterInfo2
);
47 pPrinterInfo2
->pPrintProcessor
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pPrintProcessor
- (ULONG_PTR
)pPrinterInfo2
);
48 pPrinterInfo2
->pDatatype
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pDatatype
- (ULONG_PTR
)pPrinterInfo2
);
49 pPrinterInfo2
->pParameters
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pParameters
- (ULONG_PTR
)pPrinterInfo2
);
51 if (pPrinterInfo2
->pServerName
)
52 pPrinterInfo2
->pServerName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo2
->pServerName
- (ULONG_PTR
)pPrinterInfo2
);
54 if (pPrinterInfo2
->pSecurityDescriptor
)
55 pPrinterInfo2
->pSecurityDescriptor
= (PSECURITY_DESCRIPTOR
)((ULONG_PTR
)pPrinterInfo2
->pSecurityDescriptor
- (ULONG_PTR
)pPrinterInfo2
);
57 *ppPrinterInfo
+= sizeof(PRINTER_INFO_2W
);
61 PPRINTER_INFO_3 pPrinterInfo3
= (PPRINTER_INFO_3
)(*ppPrinterInfo
);
63 pPrinterInfo3
->pSecurityDescriptor
= (PSECURITY_DESCRIPTOR
)((ULONG_PTR
)pPrinterInfo3
->pSecurityDescriptor
- (ULONG_PTR
)pPrinterInfo3
);
65 *ppPrinterInfo
+= sizeof(PRINTER_INFO_3
);
69 PPRINTER_INFO_4W pPrinterInfo4
= (PPRINTER_INFO_4W
)(*ppPrinterInfo
);
71 pPrinterInfo4
->pPrinterName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo4
->pPrinterName
- (ULONG_PTR
)pPrinterInfo4
);
73 if (pPrinterInfo4
->pServerName
)
74 pPrinterInfo4
->pServerName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo4
->pServerName
- (ULONG_PTR
)pPrinterInfo4
);
76 *ppPrinterInfo
+= sizeof(PRINTER_INFO_4W
);
80 PPRINTER_INFO_5W pPrinterInfo5
= (PPRINTER_INFO_5W
)(*ppPrinterInfo
);
82 pPrinterInfo5
->pPrinterName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo5
->pPrinterName
- (ULONG_PTR
)pPrinterInfo5
);
83 pPrinterInfo5
->pPortName
= (PWSTR
)((ULONG_PTR
)pPrinterInfo5
->pPortName
- (ULONG_PTR
)pPrinterInfo5
);
85 *ppPrinterInfo
+= sizeof(PRINTER_INFO_5W
);
89 *ppPrinterInfo
+= sizeof(PRINTER_INFO_6
);
93 PPRINTER_INFO_7W pPrinterInfo7
= (PPRINTER_INFO_7W
)(*ppPrinterInfo
);
95 if (pPrinterInfo7
->pszObjectGUID
)
96 pPrinterInfo7
->pszObjectGUID
= (PWSTR
)((ULONG_PTR
)pPrinterInfo7
->pszObjectGUID
- (ULONG_PTR
)pPrinterInfo7
);
98 *ppPrinterInfo
+= sizeof(PRINTER_INFO_7W
);
102 PPRINTER_INFO_8W pPrinterInfo8
= (PPRINTER_INFO_8W
)(*ppPrinterInfo
);
104 pPrinterInfo8
->pDevMode
= (PDEVMODEW
)((ULONG_PTR
)pPrinterInfo8
->pDevMode
- (ULONG_PTR
)pPrinterInfo8
);
106 *ppPrinterInfo
+= sizeof(PRINTER_INFO_8W
);
110 PPRINTER_INFO_9W pPrinterInfo9
= (PPRINTER_INFO_9W
)(*ppPrinterInfo
);
112 pPrinterInfo9
->pDevMode
= (PDEVMODEW
)((ULONG_PTR
)pPrinterInfo9
->pDevMode
- (ULONG_PTR
)pPrinterInfo9
);
114 *ppPrinterInfo
+= sizeof(PRINTER_INFO_9W
);
119 _RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
)
122 return ERROR_INVALID_FUNCTION
;
126 _RpcAddPrinter(WINSPOOL_HANDLE pName
, WINSPOOL_PRINTER_CONTAINER
* pPrinterContainer
, WINSPOOL_DEVMODE_CONTAINER
* pDevModeContainer
, WINSPOOL_SECURITY_CONTAINER
* pSecurityContainer
, WINSPOOL_PRINTER_HANDLE
* pHandle
)
129 return ERROR_INVALID_FUNCTION
;
133 _RpcAddPrinterEx(WINSPOOL_HANDLE pName
, WINSPOOL_PRINTER_CONTAINER
* pPrinterContainer
, WINSPOOL_DEVMODE_CONTAINER
* pDevModeContainer
, WINSPOOL_SECURITY_CONTAINER
* pSecurityContainer
, WINSPOOL_SPLCLIENT_CONTAINER
* pClientInfo
, WINSPOOL_PRINTER_HANDLE
* pHandle
)
136 return ERROR_INVALID_FUNCTION
;
140 _RpcClosePrinter(WINSPOOL_PRINTER_HANDLE
* phPrinter
)
144 dwErrorCode
= RpcImpersonateClient(NULL
);
145 if (dwErrorCode
!= ERROR_SUCCESS
)
147 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
151 if (ClosePrinter(*phPrinter
))
154 dwErrorCode
= GetLastError();
161 _RpcDeletePrinter(WINSPOOL_PRINTER_HANDLE hPrinter
)
164 return ERROR_INVALID_FUNCTION
;
168 _RpcEndDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
)
172 dwErrorCode
= RpcImpersonateClient(NULL
);
173 if (dwErrorCode
!= ERROR_SUCCESS
)
175 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
179 if (!EndDocPrinter(hPrinter
))
180 dwErrorCode
= GetLastError();
187 _RpcEndPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter
)
191 dwErrorCode
= RpcImpersonateClient(NULL
);
192 if (dwErrorCode
!= ERROR_SUCCESS
)
194 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
198 if (!EndPagePrinter(hPrinter
))
199 dwErrorCode
= GetLastError();
206 _RpcEnumPrinters(DWORD Flags
, WINSPOOL_HANDLE Name
, DWORD Level
, BYTE
* pPrinterEnum
, DWORD cbBuf
, DWORD
* pcbNeeded
, DWORD
* pcReturned
)
209 PBYTE pPrinterEnumAligned
;
211 dwErrorCode
= RpcImpersonateClient(NULL
);
212 if (dwErrorCode
!= ERROR_SUCCESS
)
214 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
218 pPrinterEnumAligned
= AlignRpcPtr(pPrinterEnum
, &cbBuf
);
220 if (EnumPrintersW(Flags
, Name
, Level
, pPrinterEnumAligned
, cbBuf
, pcbNeeded
, pcReturned
))
223 PBYTE p
= pPrinterEnumAligned
;
225 for (i
= 0; i
< *pcReturned
; i
++)
226 _MarshallDownPrinterInfo(&p
, Level
);
230 dwErrorCode
= GetLastError();
234 UndoAlignRpcPtr(pPrinterEnum
, pPrinterEnumAligned
, cbBuf
, pcbNeeded
);
240 _RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, BYTE
* pBuf
, DWORD cbBuf
, DWORD
* pcWritten
, DWORD cSleep
)
243 return ERROR_INVALID_FUNCTION
;
247 _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, DWORD Level
, BYTE
* pPrinter
, DWORD cbBuf
, DWORD
* pcbNeeded
)
250 PBYTE pPrinterAligned
;
252 dwErrorCode
= RpcImpersonateClient(NULL
);
253 if (dwErrorCode
!= ERROR_SUCCESS
)
255 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
259 pPrinterAligned
= AlignRpcPtr(pPrinter
, &cbBuf
);
261 if (GetPrinterW(hPrinter
, Level
, pPrinterAligned
, cbBuf
, pcbNeeded
))
263 PBYTE p
= pPrinterAligned
;
264 _MarshallDownPrinterInfo(&p
, Level
);
268 dwErrorCode
= GetLastError();
272 UndoAlignRpcPtr(pPrinter
, pPrinterAligned
, cbBuf
, pcbNeeded
);
278 _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName
, WINSPOOL_PRINTER_HANDLE
* phPrinter
, WCHAR
* pDatatype
, WINSPOOL_DEVMODE_CONTAINER
* pDevModeContainer
, DWORD AccessRequired
)
281 PRINTER_DEFAULTSW Default
;
283 dwErrorCode
= RpcImpersonateClient(NULL
);
284 if (dwErrorCode
!= ERROR_SUCCESS
)
286 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
290 Default
.DesiredAccess
= AccessRequired
;
291 Default
.pDatatype
= pDatatype
;
292 Default
.pDevMode
= (PDEVMODEW
)pDevModeContainer
->pDevMode
;
294 if (!OpenPrinterW(pPrinterName
, phPrinter
, &Default
))
295 dwErrorCode
= GetLastError();
302 _RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName
, WINSPOOL_PRINTER_HANDLE
* pHandle
, WCHAR
* pDatatype
, WINSPOOL_DEVMODE_CONTAINER
* pDevModeContainer
, DWORD AccessRequired
, WINSPOOL_SPLCLIENT_CONTAINER
* pClientInfo
)
305 return ERROR_INVALID_FUNCTION
;
309 _RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, BYTE
* pBuf
, DWORD cbBuf
, DWORD
* pcNoBytesRead
)
313 dwErrorCode
= RpcImpersonateClient(NULL
);
314 if (dwErrorCode
!= ERROR_SUCCESS
)
316 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
320 if (!ReadPrinter(hPrinter
, pBuf
, cbBuf
, pcNoBytesRead
))
321 dwErrorCode
= GetLastError();
328 _RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, WCHAR
* pDatatype
, WINSPOOL_DEVMODE_CONTAINER
* pDevModeContainer
)
331 return ERROR_INVALID_FUNCTION
;
335 _RpcResetPrinterEx(VOID
)
338 return ERROR_INVALID_FUNCTION
;
342 _RpcSeekPrinter(VOID
)
345 return ERROR_INVALID_FUNCTION
;
349 _RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, WINSPOOL_PRINTER_CONTAINER
* pPrinterContainer
, WINSPOOL_DEVMODE_CONTAINER
* pDevModeContainer
, WINSPOOL_SECURITY_CONTAINER
* pSecurityContainer
, DWORD Command
)
352 return ERROR_INVALID_FUNCTION
;
356 _RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, WINSPOOL_DOC_INFO_CONTAINER
* pDocInfoContainer
, DWORD
* pJobId
)
360 dwErrorCode
= RpcImpersonateClient(NULL
);
361 if (dwErrorCode
!= ERROR_SUCCESS
)
363 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
367 *pJobId
= StartDocPrinterW(hPrinter
, pDocInfoContainer
->Level
, (PBYTE
)pDocInfoContainer
->DocInfo
.pDocInfo1
);
368 dwErrorCode
= GetLastError();
375 _RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter
)
379 dwErrorCode
= RpcImpersonateClient(NULL
);
380 if (dwErrorCode
!= ERROR_SUCCESS
)
382 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
386 if (!StartPagePrinter(hPrinter
))
387 dwErrorCode
= GetLastError();
394 _RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter
, BYTE
* pBuf
, DWORD cbBuf
, DWORD
* pcWritten
)
398 dwErrorCode
= RpcImpersonateClient(NULL
);
399 if (dwErrorCode
!= ERROR_SUCCESS
)
401 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode
);
405 if (!WritePrinter(hPrinter
, pBuf
, cbBuf
, pcWritten
))
406 dwErrorCode
= GetLastError();