596cddbf35cc686bccfe974a0da7042d0a47c5fc
[reactos.git] / win32ss / printing / base / spoolsv / jobs.c
1 /*
2 * PROJECT: ReactOS Print Spooler Service
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions for managing print jobs
5 * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 static void
11 _MarshallDownAddJobInfo(PADDJOB_INFO_1W* ppAddJobInfo1)
12 {
13 // Replace absolute pointer addresses in the output by relative offsets.
14 PADDJOB_INFO_1W pAddJobInfo1 = *ppAddJobInfo1;
15 pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path - (ULONG_PTR)pAddJobInfo1);
16
17 *ppAddJobInfo1 += sizeof(ADDJOB_INFO_1W);
18 }
19
20 static void
21 _MarshallDownJobInfo(PBYTE* ppJobInfo, DWORD Level)
22 {
23 // Replace absolute pointer addresses in the output by relative offsets.
24 if (Level == 1)
25 {
26 PJOB_INFO_1W pJobInfo1 = (PJOB_INFO_1W)(*ppJobInfo);
27
28 pJobInfo1->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo1->pDatatype - (ULONG_PTR)pJobInfo1);
29 pJobInfo1->pDocument = (PWSTR)((ULONG_PTR)pJobInfo1->pDocument - (ULONG_PTR)pJobInfo1);
30 pJobInfo1->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo1->pMachineName - (ULONG_PTR)pJobInfo1);
31 pJobInfo1->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo1->pPrinterName - (ULONG_PTR)pJobInfo1);
32
33 if (pJobInfo1->pStatus)
34 pJobInfo1->pStatus = (PWSTR)((ULONG_PTR)pJobInfo1->pStatus - (ULONG_PTR)pJobInfo1);
35
36 pJobInfo1->pUserName = (PWSTR)((ULONG_PTR)pJobInfo1->pUserName - (ULONG_PTR)pJobInfo1);
37
38 *ppJobInfo += sizeof(JOB_INFO_1W);
39 }
40 else if (Level == 2)
41 {
42 PJOB_INFO_2W pJobInfo2 = (PJOB_INFO_2W)(*ppJobInfo);
43
44 pJobInfo2->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo2->pDatatype - (ULONG_PTR)pJobInfo2);
45 pJobInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pJobInfo2->pDevMode - (ULONG_PTR)pJobInfo2);
46 pJobInfo2->pDocument = (PWSTR)((ULONG_PTR)pJobInfo2->pDocument - (ULONG_PTR)pJobInfo2);
47 pJobInfo2->pDriverName = (PWSTR)((ULONG_PTR)pJobInfo2->pDriverName - (ULONG_PTR)pJobInfo2);
48 pJobInfo2->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo2->pMachineName - (ULONG_PTR)pJobInfo2);
49 pJobInfo2->pNotifyName = (PWSTR)((ULONG_PTR)pJobInfo2->pNotifyName - (ULONG_PTR)pJobInfo2);
50 pJobInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo2->pPrinterName - (ULONG_PTR)pJobInfo2);
51 pJobInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pJobInfo2->pPrintProcessor - (ULONG_PTR)pJobInfo2);
52
53 if (pJobInfo2->pParameters)
54 pJobInfo2->pParameters = (PWSTR)((ULONG_PTR)pJobInfo2->pParameters - (ULONG_PTR)pJobInfo2);
55
56 if (pJobInfo2->pStatus)
57 pJobInfo2->pStatus = (PWSTR)((ULONG_PTR)pJobInfo2->pStatus - (ULONG_PTR)pJobInfo2);
58
59 pJobInfo2->pUserName = (PWSTR)((ULONG_PTR)pJobInfo2->pUserName - (ULONG_PTR)pJobInfo2);
60
61 *ppJobInfo += sizeof(JOB_INFO_2W);
62 }
63 }
64
65 DWORD
66 _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD cbBuf, DWORD* pcbNeeded)
67 {
68 DWORD dwErrorCode;
69 PBYTE pAddJobAligned;
70
71 dwErrorCode = RpcImpersonateClient(NULL);
72 if (dwErrorCode != ERROR_SUCCESS)
73 {
74 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
75 return dwErrorCode;
76 }
77
78 pAddJobAligned = AlignRpcPtr(pAddJob, &cbBuf);
79
80 if (AddJobW(hPrinter, Level, pAddJobAligned, cbBuf, pcbNeeded))
81 {
82 PBYTE p = pAddJobAligned;
83
84 // Replace absolute pointer addresses in the output by relative offsets.
85 _MarshallDownAddJobInfo((PADDJOB_INFO_1W*)&p);
86 }
87 else
88 {
89 dwErrorCode = GetLastError();
90 }
91
92 RpcRevertToSelf();
93 UndoAlignRpcPtr(pAddJob, pAddJobAligned, cbBuf, pcbNeeded);
94
95 return dwErrorCode;
96 }
97
98 DWORD
99 _RpcEnumJobs(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
100 {
101 DWORD dwErrorCode;
102 PBYTE pJobAligned;
103
104 dwErrorCode = RpcImpersonateClient(NULL);
105 if (dwErrorCode != ERROR_SUCCESS)
106 {
107 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
108 return dwErrorCode;
109 }
110
111 pJobAligned = AlignRpcPtr(pJob, &cbBuf);
112
113 if (EnumJobsW(hPrinter, FirstJob, NoJobs, Level, pJobAligned, cbBuf, pcbNeeded, pcReturned))
114 {
115 DWORD i;
116 PBYTE p = pJobAligned;
117
118 // Replace absolute pointer addresses in the output by relative offsets.
119 for (i = 0; i < *pcReturned; i++)
120 _MarshallDownJobInfo(&p, Level);
121 }
122 else
123 {
124 dwErrorCode = GetLastError();
125 }
126
127 RpcRevertToSelf();
128 UndoAlignRpcPtr(pJob, pJobAligned, cbBuf, pcbNeeded);
129
130 return dwErrorCode;
131 }
132
133 DWORD
134 _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded)
135 {
136 DWORD dwErrorCode;
137 PBYTE pJobAligned;
138
139 dwErrorCode = RpcImpersonateClient(NULL);
140 if (dwErrorCode != ERROR_SUCCESS)
141 {
142 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
143 return dwErrorCode;
144 }
145
146 pJobAligned = AlignRpcPtr(pJob, &cbBuf);
147
148 if (GetJobW(hPrinter, JobId, Level, pJobAligned, cbBuf, pcbNeeded))
149 {
150 PBYTE p = pJobAligned;
151
152 // Replace absolute pointer addresses in the output by relative offsets.
153 _MarshallDownJobInfo(&p, Level);
154 }
155 else
156 {
157 dwErrorCode = GetLastError();
158 }
159
160 RpcRevertToSelf();
161 UndoAlignRpcPtr(pJob, pJobAligned, cbBuf, pcbNeeded);
162
163 return dwErrorCode;
164 }
165
166 DWORD
167 _RpcScheduleJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId)
168 {
169 DWORD dwErrorCode;
170
171 dwErrorCode = RpcImpersonateClient(NULL);
172 if (dwErrorCode != ERROR_SUCCESS)
173 {
174 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
175 return dwErrorCode;
176 }
177
178 if (!ScheduleJob(hPrinter, JobId))
179 dwErrorCode = GetLastError();
180
181 RpcRevertToSelf();
182 return dwErrorCode;
183 }
184
185 DWORD
186 _RpcSetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, WINSPOOL_JOB_CONTAINER* pJobContainer, DWORD Command)
187 {
188 DWORD dwErrorCode;
189
190 dwErrorCode = RpcImpersonateClient(NULL);
191 if (dwErrorCode != ERROR_SUCCESS)
192 {
193 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
194 return dwErrorCode;
195 }
196
197 // pJobContainer->JobInfo is a union of pointers, so we can just convert any element to our BYTE pointer.
198 if (!SetJobW(hPrinter, JobId, pJobContainer->Level, (PBYTE)pJobContainer->JobInfo.Level1, Command))
199 dwErrorCode = GetLastError();
200
201 RpcRevertToSelf();
202 return dwErrorCode;
203 }