7551a30b3300bf78004120d4343360eeafc91c32
[reactos.git] / win32ss / printing / base / winspool / jobs.c
1 /*
2 * PROJECT: ReactOS Spooler API
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 _MarshallUpAddJobInfo(PADDJOB_INFO_1W pAddJobInfo1)
12 {
13 // Replace relative offset addresses in the output by absolute pointers.
14 pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path + (ULONG_PTR)pAddJobInfo1);
15 }
16
17 static void
18 _MarshallUpJobInfo(PBYTE pJobInfo, DWORD Level)
19 {
20 PJOB_INFO_1W pJobInfo1;
21 PJOB_INFO_2W pJobInfo2;
22
23 // Replace relative offset addresses in the output by absolute pointers.
24 if (Level == 1)
25 {
26 pJobInfo1 = (PJOB_INFO_1W)pJobInfo;
27 pJobInfo1->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo1->pDatatype + (ULONG_PTR)pJobInfo1);
28 pJobInfo1->pDocument = (PWSTR)((ULONG_PTR)pJobInfo1->pDocument + (ULONG_PTR)pJobInfo1);
29 pJobInfo1->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo1->pMachineName + (ULONG_PTR)pJobInfo1);
30 pJobInfo1->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo1->pPrinterName + (ULONG_PTR)pJobInfo1);
31
32 if (pJobInfo1->pStatus)
33 pJobInfo1->pStatus = (PWSTR)((ULONG_PTR)pJobInfo1->pStatus + (ULONG_PTR)pJobInfo1);
34
35 pJobInfo1->pUserName = (PWSTR)((ULONG_PTR)pJobInfo1->pUserName + (ULONG_PTR)pJobInfo1);
36 }
37 else if (Level == 2)
38 {
39 pJobInfo2 = (PJOB_INFO_2W)pJobInfo;
40 pJobInfo2->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo2->pDatatype + (ULONG_PTR)pJobInfo2);
41 pJobInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pJobInfo2->pDevMode + (ULONG_PTR)pJobInfo2);
42 pJobInfo2->pDocument = (PWSTR)((ULONG_PTR)pJobInfo2->pDocument + (ULONG_PTR)pJobInfo2);
43 pJobInfo2->pDriverName = (PWSTR)((ULONG_PTR)pJobInfo2->pDriverName + (ULONG_PTR)pJobInfo2);
44 pJobInfo2->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo2->pMachineName + (ULONG_PTR)pJobInfo2);
45 pJobInfo2->pNotifyName = (PWSTR)((ULONG_PTR)pJobInfo2->pNotifyName + (ULONG_PTR)pJobInfo2);
46 pJobInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo2->pPrinterName + (ULONG_PTR)pJobInfo2);
47 pJobInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pJobInfo2->pPrintProcessor + (ULONG_PTR)pJobInfo2);
48
49 if (pJobInfo2->pParameters)
50 pJobInfo2->pParameters = (PWSTR)((ULONG_PTR)pJobInfo2->pParameters + (ULONG_PTR)pJobInfo2);
51
52 if (pJobInfo2->pStatus)
53 pJobInfo2->pStatus = (PWSTR)((ULONG_PTR)pJobInfo2->pStatus + (ULONG_PTR)pJobInfo2);
54
55 pJobInfo2->pUserName = (PWSTR)((ULONG_PTR)pJobInfo2->pUserName + (ULONG_PTR)pJobInfo2);
56 }
57 }
58
59 BOOL WINAPI
60 AddJobA(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
61 {
62 TRACE("AddJobA(%p, %lu, %p, %lu, %p)\n", hPrinter, Level, pData, cbBuf, pcbNeeded);
63 UNIMPLEMENTED;
64 return FALSE;
65 }
66
67 BOOL WINAPI
68 AddJobW(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
69 {
70 DWORD dwErrorCode;
71 PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
72
73 TRACE("AddJobW(%p, %lu, %p, %lu, %p)\n", hPrinter, Level, pData, cbBuf, pcbNeeded);
74
75 if (!pHandle)
76 {
77 dwErrorCode = ERROR_INVALID_HANDLE;
78 goto Cleanup;
79 }
80
81 // Do the RPC call
82 RpcTryExcept
83 {
84 dwErrorCode = _RpcAddJob(pHandle->hPrinter, Level, pData, cbBuf, pcbNeeded);
85 }
86 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
87 {
88 dwErrorCode = RpcExceptionCode();
89 ERR("_RpcAddJob failed with exception code %lu!\n", dwErrorCode);
90 }
91 RpcEndExcept;
92
93 if (dwErrorCode == ERROR_SUCCESS)
94 _MarshallUpAddJobInfo((PADDJOB_INFO_1W)pData);
95
96 Cleanup:
97 SetLastError(dwErrorCode);
98 return (dwErrorCode == ERROR_SUCCESS);
99 }
100
101 BOOL WINAPI
102 EnumJobsA(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
103 {
104 TRACE("EnumJobsA(%p, %lu, %lu, %lu, %p, %lu, %p, %p)\n", hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
105 UNIMPLEMENTED;
106 return FALSE;
107 }
108
109 BOOL WINAPI
110 EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
111 {
112 DWORD dwErrorCode;
113 DWORD i;
114 PBYTE p = pJob;
115 PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
116
117 TRACE("EnumJobsW(%p, %lu, %lu, %lu, %p, %lu, %p, %p)\n", hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
118
119 if (!pHandle)
120 {
121 dwErrorCode = ERROR_INVALID_HANDLE;
122 goto Cleanup;
123 }
124
125 // Do the RPC call
126 RpcTryExcept
127 {
128 dwErrorCode = _RpcEnumJobs(pHandle->hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
129 }
130 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
131 {
132 dwErrorCode = RpcExceptionCode();
133 ERR("_RpcEnumJobs failed with exception code %lu!\n", dwErrorCode);
134 }
135 RpcEndExcept;
136
137 if (dwErrorCode == ERROR_SUCCESS)
138 {
139 // Replace relative offset addresses in the output by absolute pointers.
140 for (i = 0; i < *pcReturned; i++)
141 {
142 _MarshallUpJobInfo(p, Level);
143
144 if (Level == 1)
145 p += sizeof(JOB_INFO_1W);
146 else if (Level == 2)
147 p += sizeof(JOB_INFO_2W);
148 }
149 }
150
151 Cleanup:
152 SetLastError(dwErrorCode);
153 return (dwErrorCode == ERROR_SUCCESS);
154 }
155
156 BOOL WINAPI
157 GetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded)
158 {
159 TRACE("GetJobA(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
160 UNIMPLEMENTED;
161 return FALSE;
162 }
163
164 BOOL WINAPI
165 GetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded)
166 {
167 DWORD dwErrorCode;
168 PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
169
170 TRACE("GetJobW(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
171
172 if (!pHandle)
173 {
174 dwErrorCode = ERROR_INVALID_HANDLE;
175 goto Cleanup;
176 }
177
178 // Do the RPC call
179 RpcTryExcept
180 {
181 dwErrorCode = _RpcGetJob(pHandle->hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
182 }
183 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
184 {
185 dwErrorCode = RpcExceptionCode();
186 ERR("_RpcGetJob failed with exception code %lu!\n", dwErrorCode);
187 }
188 RpcEndExcept;
189
190 if (dwErrorCode == ERROR_SUCCESS)
191 {
192 // Replace relative offset addresses in the output by absolute pointers.
193 _MarshallUpJobInfo(pJob, Level);
194 }
195
196 Cleanup:
197 SetLastError(dwErrorCode);
198 return (dwErrorCode == ERROR_SUCCESS);
199 }
200
201 BOOL WINAPI
202 ScheduleJob(HANDLE hPrinter, DWORD dwJobID)
203 {
204 DWORD dwErrorCode;
205 PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
206
207 TRACE("ScheduleJob(%p, %lu)\n", hPrinter, dwJobID);
208
209 if (!pHandle)
210 {
211 dwErrorCode = ERROR_INVALID_HANDLE;
212 goto Cleanup;
213 }
214
215 // Do the RPC call
216 RpcTryExcept
217 {
218 dwErrorCode = _RpcScheduleJob(pHandle->hPrinter, dwJobID);
219 }
220 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
221 {
222 dwErrorCode = RpcExceptionCode();
223 ERR("_RpcScheduleJob failed with exception code %lu!\n", dwErrorCode);
224 }
225 RpcEndExcept;
226
227 Cleanup:
228 SetLastError(dwErrorCode);
229 return (dwErrorCode == ERROR_SUCCESS);
230 }
231
232 BOOL WINAPI
233 SetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
234 {
235 TRACE("SetJobA(%p, %lu, %lu, %p, %lu)\n", hPrinter, JobId, Level, pJobInfo, Command);
236 UNIMPLEMENTED;
237 return FALSE;
238 }
239
240 BOOL WINAPI
241 SetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
242 {
243 DWORD dwErrorCode;
244 PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
245 WINSPOOL_JOB_CONTAINER JobContainer;
246
247 TRACE("SetJobW(%p, %lu, %lu, %p, %lu)\n", hPrinter, JobId, Level, pJobInfo, Command);
248
249 if (!pHandle)
250 {
251 dwErrorCode = ERROR_INVALID_HANDLE;
252 goto Cleanup;
253 }
254
255 // pJobContainer->JobInfo is a union of pointers, so we can just set any element to our BYTE pointer.
256 JobContainer.Level = Level;
257 JobContainer.JobInfo.Level1 = (WINSPOOL_JOB_INFO_1*)pJobInfo;
258
259 // Do the RPC call
260 RpcTryExcept
261 {
262 dwErrorCode = _RpcSetJob(pHandle->hPrinter, JobId, &JobContainer, Command);
263 }
264 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
265 {
266 dwErrorCode = RpcExceptionCode();
267 ERR("_RpcSetJob failed with exception code %lu!\n", dwErrorCode);
268 }
269 RpcEndExcept;
270
271 Cleanup:
272 SetLastError(dwErrorCode);
273 return (dwErrorCode == ERROR_SUCCESS);
274 }