[SPOOLSS, SPOOLSV, WINSPOOL]
[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 _MarshallDownJobInfo(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 DWORD
53 _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD cbBuf, DWORD* pcbNeeded)
54 {
55 DWORD dwErrorCode;
56 PADDJOB_INFO_1W pAddJobInfo1;
57
58 dwErrorCode = RpcImpersonateClient(NULL);
59 if (dwErrorCode != ERROR_SUCCESS)
60 {
61 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
62 return dwErrorCode;
63 }
64
65 AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
66 dwErrorCode = GetLastError();
67
68 if (dwErrorCode == ERROR_SUCCESS)
69 {
70 // Replace absolute pointer addresses in the output by relative offsets.
71 pAddJobInfo1 = (PADDJOB_INFO_1W)pAddJob;
72 pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path - (ULONG_PTR)pAddJobInfo1);
73 }
74
75 RpcRevertToSelf();
76 return dwErrorCode;
77 }
78
79 DWORD
80 _RpcEnumJobs(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
81 {
82 DWORD dwErrorCode;
83 DWORD i;
84 PBYTE p = pJob;
85
86 dwErrorCode = RpcImpersonateClient(NULL);
87 if (dwErrorCode != ERROR_SUCCESS)
88 {
89 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
90 return dwErrorCode;
91 }
92
93 EnumJobsW(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
94 dwErrorCode = GetLastError();
95
96 if (dwErrorCode == ERROR_SUCCESS)
97 {
98 // Replace absolute pointer addresses in the output by relative offsets.
99 for (i = 0; i < *pcReturned; i++)
100 {
101 _MarshallDownJobInfo(p, Level);
102
103 if (Level == 1)
104 p += sizeof(JOB_INFO_1W);
105 else if (Level == 2)
106 p += sizeof(JOB_INFO_2W);
107 }
108 }
109
110 RpcRevertToSelf();
111 return dwErrorCode;
112 }
113
114 DWORD
115 _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded)
116 {
117 DWORD dwErrorCode;
118
119 dwErrorCode = RpcImpersonateClient(NULL);
120 if (dwErrorCode != ERROR_SUCCESS)
121 {
122 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
123 return dwErrorCode;
124 }
125
126 GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
127 dwErrorCode = GetLastError();
128
129 if (dwErrorCode == ERROR_SUCCESS)
130 {
131 // Replace absolute pointer addresses in the output by relative offsets.
132 _MarshallDownJobInfo(pJob, Level);
133 }
134
135 RpcRevertToSelf();
136 return dwErrorCode;
137 }
138
139 DWORD
140 _RpcScheduleJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId)
141 {
142 UNIMPLEMENTED;
143 return ERROR_INVALID_FUNCTION;
144 }
145
146 DWORD
147 _RpcSetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, WINSPOOL_JOB_CONTAINER* pJobContainer, DWORD Command)
148 {
149 DWORD dwErrorCode;
150
151 dwErrorCode = RpcImpersonateClient(NULL);
152 if (dwErrorCode != ERROR_SUCCESS)
153 {
154 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
155 return dwErrorCode;
156 }
157
158 // pJobContainer->JobInfo is a union of pointers, so we can just convert any element to our BYTE pointer.
159 SetJobW(hPrinter, JobId, pJobContainer->Level, (PBYTE)pJobContainer->JobInfo.Level1, Command);
160 dwErrorCode = GetLastError();
161
162 RpcRevertToSelf();
163 return dwErrorCode;
164 }