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