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>
11 _MarshallUpJobInfo(PBYTE pJobInfo
, DWORD Level
)
13 PJOB_INFO_1W pJobInfo1
;
14 PJOB_INFO_2W pJobInfo2
;
16 // Replace absolute pointer addresses in the output by relative offsets.
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
);
25 if (pJobInfo1
->pStatus
)
26 pJobInfo1
->pStatus
= (PWSTR
)((ULONG_PTR
)pJobInfo1
->pStatus
+ (ULONG_PTR
)pJobInfo1
);
28 pJobInfo1
->pUserName
= (PWSTR
)((ULONG_PTR
)pJobInfo1
->pUserName
+ (ULONG_PTR
)pJobInfo1
);
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
);
42 if (pJobInfo2
->pParameters
)
43 pJobInfo2
->pParameters
= (PWSTR
)((ULONG_PTR
)pJobInfo2
->pParameters
+ (ULONG_PTR
)pJobInfo2
);
45 if (pJobInfo2
->pStatus
)
46 pJobInfo2
->pStatus
= (PWSTR
)((ULONG_PTR
)pJobInfo2
->pStatus
+ (ULONG_PTR
)pJobInfo2
);
48 pJobInfo2
->pUserName
= (PWSTR
)((ULONG_PTR
)pJobInfo2
->pUserName
+ (ULONG_PTR
)pJobInfo2
);
53 AddJobA(HANDLE hPrinter
, DWORD Level
, PBYTE pData
, DWORD cbBuf
, PDWORD pcbNeeded
)
60 AddJobW(HANDLE hPrinter
, DWORD Level
, PBYTE pData
, DWORD cbBuf
, PDWORD pcbNeeded
)
63 PADDJOB_INFO_1W pAddJobInfo1
;
64 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
68 dwErrorCode
= ERROR_INVALID_HANDLE
;
75 dwErrorCode
= _RpcAddJob(pHandle
->hPrinter
, Level
, pData
, cbBuf
, pcbNeeded
);
77 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
79 dwErrorCode
= RpcExceptionCode();
80 ERR("_RpcAddJob failed with exception code %lu!\n", dwErrorCode
);
84 if (dwErrorCode
== ERROR_SUCCESS
)
86 // Replace relative offset addresses in the output by absolute pointers.
87 pAddJobInfo1
= (PADDJOB_INFO_1W
)pData
;
88 pAddJobInfo1
->Path
= (PWSTR
)((ULONG_PTR
)pAddJobInfo1
->Path
+ (ULONG_PTR
)pAddJobInfo1
);
92 SetLastError(dwErrorCode
);
93 return (dwErrorCode
== ERROR_SUCCESS
);
97 EnumJobsA(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
104 EnumJobsW(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
109 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
113 dwErrorCode
= ERROR_INVALID_HANDLE
;
120 dwErrorCode
= _RpcEnumJobs(pHandle
->hPrinter
, FirstJob
, NoJobs
, Level
, pJob
, cbBuf
, pcbNeeded
, pcReturned
);
122 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
124 dwErrorCode
= RpcExceptionCode();
125 ERR("_RpcEnumJobs failed with exception code %lu!\n", dwErrorCode
);
129 if (dwErrorCode
== ERROR_SUCCESS
)
131 // Replace relative offset addresses in the output by absolute pointers.
132 for (i
= 0; i
< *pcReturned
; i
++)
134 _MarshallUpJobInfo(p
, Level
);
137 p
+= sizeof(JOB_INFO_1W
);
139 p
+= sizeof(JOB_INFO_2W
);
144 SetLastError(dwErrorCode
);
145 return (dwErrorCode
== ERROR_SUCCESS
);
149 GetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
)
156 GetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
)
159 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
163 dwErrorCode
= ERROR_INVALID_HANDLE
;
170 dwErrorCode
= _RpcGetJob(pHandle
->hPrinter
, JobId
, Level
, pJob
, cbBuf
, pcbNeeded
);
172 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
174 dwErrorCode
= RpcExceptionCode();
175 ERR("_RpcGetJob failed with exception code %lu!\n", dwErrorCode
);
179 if (dwErrorCode
== ERROR_SUCCESS
)
181 // Replace relative offset addresses in the output by absolute pointers.
182 _MarshallUpJobInfo(pJob
, Level
);
186 SetLastError(dwErrorCode
);
187 return (dwErrorCode
== ERROR_SUCCESS
);
191 ScheduleJob(HANDLE hPrinter
, DWORD dwJobID
)
194 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
198 dwErrorCode
= ERROR_INVALID_HANDLE
;
205 dwErrorCode
= _RpcScheduleJob(pHandle
->hPrinter
, dwJobID
);
207 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
209 dwErrorCode
= RpcExceptionCode();
210 ERR("_RpcScheduleJob failed with exception code %lu!\n", dwErrorCode
);
215 SetLastError(dwErrorCode
);
216 return (dwErrorCode
== ERROR_SUCCESS
);
220 SetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJobInfo
, DWORD Command
)
227 SetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJobInfo
, DWORD Command
)
230 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
231 WINSPOOL_JOB_CONTAINER JobContainer
;
235 dwErrorCode
= ERROR_INVALID_HANDLE
;
239 // pJobContainer->JobInfo is a union of pointers, so we can just set any element to our BYTE pointer.
240 JobContainer
.Level
= Level
;
241 JobContainer
.JobInfo
.Level1
= (WINSPOOL_JOB_INFO_1
*)pJobInfo
;
246 dwErrorCode
= _RpcSetJob(pHandle
->hPrinter
, JobId
, &JobContainer
, Command
);
248 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
250 dwErrorCode
= RpcExceptionCode();
251 ERR("_RpcSetJob failed with exception code %lu!\n", dwErrorCode
);
256 SetLastError(dwErrorCode
);
257 return (dwErrorCode
== ERROR_SUCCESS
);