[SPOOLSS]
[reactos.git] / reactos / win32ss / printing / base / spoolsv / jobs.c
1 /*
2 * PROJECT: ReactOS Print Spooler Service
3 * LICENSE: GNU GPLv2 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 _MarshallDownAddJobInfo(PADDJOB_INFO_1W pAddJobInfo1)
12 {
13 // Replace absolute pointer addresses in the output by relative offsets.
14 pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path - (ULONG_PTR)pAddJobInfo1);
15 }
16
17 static void
18 _MarshallDownJobInfo(PBYTE pJobInfo, DWORD Level)
19 {
20 PJOB_INFO_1W pJobInfo1;
21 PJOB_INFO_2W pJobInfo2;
22
23 // Replace absolute pointer addresses in the output by relative offsets.
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 DWORD
60 _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD cbBuf, DWORD* pcbNeeded)
61 {
62 DWORD dwErrorCode;
63
64 dwErrorCode = RpcImpersonateClient(NULL);
65 if (dwErrorCode != ERROR_SUCCESS)
66 {
67 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
68 return dwErrorCode;
69 }
70
71 AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
72 dwErrorCode = GetLastError();
73
74 if (dwErrorCode == ERROR_SUCCESS)
75 _MarshallDownAddJobInfo((PADDJOB_INFO_1W)pAddJob);
76
77 RpcRevertToSelf();
78 return dwErrorCode;
79 }
80
81 DWORD
82 _RpcEnumJobs(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
83 {
84 DWORD dwErrorCode;
85 DWORD i;
86 PBYTE p = pJob;
87
88 dwErrorCode = RpcImpersonateClient(NULL);
89 if (dwErrorCode != ERROR_SUCCESS)
90 {
91 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
92 return dwErrorCode;
93 }
94
95 EnumJobsW(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
96 dwErrorCode = GetLastError();
97
98 if (dwErrorCode == ERROR_SUCCESS)
99 {
100 // Replace absolute pointer addresses in the output by relative offsets.
101 for (i = 0; i < *pcReturned; i++)
102 {
103 _MarshallDownJobInfo(p, Level);
104
105 if (Level == 1)
106 p += sizeof(JOB_INFO_1W);
107 else if (Level == 2)
108 p += sizeof(JOB_INFO_2W);
109 }
110 }
111
112 RpcRevertToSelf();
113 return dwErrorCode;
114 }
115
116 DWORD
117 _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded)
118 {
119 DWORD dwErrorCode;
120
121 dwErrorCode = RpcImpersonateClient(NULL);
122 if (dwErrorCode != ERROR_SUCCESS)
123 {
124 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
125 return dwErrorCode;
126 }
127
128 GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
129 dwErrorCode = GetLastError();
130
131 if (dwErrorCode == ERROR_SUCCESS)
132 {
133 // Replace absolute pointer addresses in the output by relative offsets.
134 _MarshallDownJobInfo(pJob, Level);
135 }
136
137 RpcRevertToSelf();
138 return dwErrorCode;
139 }
140
141 DWORD
142 _RpcScheduleJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId)
143 {
144 DWORD dwErrorCode;
145
146 dwErrorCode = RpcImpersonateClient(NULL);
147 if (dwErrorCode != ERROR_SUCCESS)
148 {
149 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
150 return dwErrorCode;
151 }
152
153 ScheduleJob(hPrinter, JobId);
154 dwErrorCode = GetLastError();
155
156 RpcRevertToSelf();
157 return dwErrorCode;
158 }
159
160 DWORD
161 _RpcSetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, WINSPOOL_JOB_CONTAINER* pJobContainer, DWORD Command)
162 {
163 DWORD dwErrorCode;
164
165 dwErrorCode = RpcImpersonateClient(NULL);
166 if (dwErrorCode != ERROR_SUCCESS)
167 {
168 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
169 return dwErrorCode;
170 }
171
172 // pJobContainer->JobInfo is a union of pointers, so we can just convert any element to our BYTE pointer.
173 SetJobW(hPrinter, JobId, pJobContainer->Level, (PBYTE)pJobContainer->JobInfo.Level1, Command);
174 dwErrorCode = GetLastError();
175
176 RpcRevertToSelf();
177 return dwErrorCode;
178 }