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 _MarshallUpAddJobInfo(PADDJOB_INFO_1W pAddJobInfo1
)
13 // Replace relative offset addresses in the output by absolute pointers.
14 pAddJobInfo1
->Path
= (PWSTR
)((ULONG_PTR
)pAddJobInfo1
->Path
+ (ULONG_PTR
)pAddJobInfo1
);
18 _MarshallUpJobInfo(PBYTE pJobInfo
, DWORD Level
)
20 PJOB_INFO_1W pJobInfo1
;
21 PJOB_INFO_2W pJobInfo2
;
23 // Replace relative offset addresses in the output by absolute pointers.
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
);
32 if (pJobInfo1
->pStatus
)
33 pJobInfo1
->pStatus
= (PWSTR
)((ULONG_PTR
)pJobInfo1
->pStatus
+ (ULONG_PTR
)pJobInfo1
);
35 pJobInfo1
->pUserName
= (PWSTR
)((ULONG_PTR
)pJobInfo1
->pUserName
+ (ULONG_PTR
)pJobInfo1
);
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
);
49 if (pJobInfo2
->pParameters
)
50 pJobInfo2
->pParameters
= (PWSTR
)((ULONG_PTR
)pJobInfo2
->pParameters
+ (ULONG_PTR
)pJobInfo2
);
52 if (pJobInfo2
->pStatus
)
53 pJobInfo2
->pStatus
= (PWSTR
)((ULONG_PTR
)pJobInfo2
->pStatus
+ (ULONG_PTR
)pJobInfo2
);
55 pJobInfo2
->pUserName
= (PWSTR
)((ULONG_PTR
)pJobInfo2
->pUserName
+ (ULONG_PTR
)pJobInfo2
);
60 AddJobA(HANDLE hPrinter
, DWORD Level
, PBYTE pData
, DWORD cbBuf
, PDWORD pcbNeeded
)
67 AddJobW(HANDLE hPrinter
, DWORD Level
, PBYTE pData
, DWORD cbBuf
, PDWORD pcbNeeded
)
70 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
74 dwErrorCode
= ERROR_INVALID_HANDLE
;
81 dwErrorCode
= _RpcAddJob(pHandle
->hPrinter
, Level
, pData
, cbBuf
, pcbNeeded
);
83 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
85 dwErrorCode
= RpcExceptionCode();
86 ERR("_RpcAddJob failed with exception code %lu!\n", dwErrorCode
);
90 if (dwErrorCode
== ERROR_SUCCESS
)
91 _MarshallUpAddJobInfo((PADDJOB_INFO_1W
)pData
);
94 SetLastError(dwErrorCode
);
95 return (dwErrorCode
== ERROR_SUCCESS
);
99 EnumJobsA(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
106 EnumJobsW(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
111 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
115 dwErrorCode
= ERROR_INVALID_HANDLE
;
122 dwErrorCode
= _RpcEnumJobs(pHandle
->hPrinter
, FirstJob
, NoJobs
, Level
, pJob
, cbBuf
, pcbNeeded
, pcReturned
);
124 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
126 dwErrorCode
= RpcExceptionCode();
127 ERR("_RpcEnumJobs failed with exception code %lu!\n", dwErrorCode
);
131 if (dwErrorCode
== ERROR_SUCCESS
)
133 // Replace relative offset addresses in the output by absolute pointers.
134 for (i
= 0; i
< *pcReturned
; i
++)
136 _MarshallUpJobInfo(p
, Level
);
139 p
+= sizeof(JOB_INFO_1W
);
141 p
+= sizeof(JOB_INFO_2W
);
146 SetLastError(dwErrorCode
);
147 return (dwErrorCode
== ERROR_SUCCESS
);
151 GetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
)
158 GetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
)
161 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
165 dwErrorCode
= ERROR_INVALID_HANDLE
;
172 dwErrorCode
= _RpcGetJob(pHandle
->hPrinter
, JobId
, Level
, pJob
, cbBuf
, pcbNeeded
);
174 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
176 dwErrorCode
= RpcExceptionCode();
177 ERR("_RpcGetJob failed with exception code %lu!\n", dwErrorCode
);
181 if (dwErrorCode
== ERROR_SUCCESS
)
183 // Replace relative offset addresses in the output by absolute pointers.
184 _MarshallUpJobInfo(pJob
, Level
);
188 SetLastError(dwErrorCode
);
189 return (dwErrorCode
== ERROR_SUCCESS
);
193 ScheduleJob(HANDLE hPrinter
, DWORD dwJobID
)
196 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
200 dwErrorCode
= ERROR_INVALID_HANDLE
;
207 dwErrorCode
= _RpcScheduleJob(pHandle
->hPrinter
, dwJobID
);
209 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
211 dwErrorCode
= RpcExceptionCode();
212 ERR("_RpcScheduleJob failed with exception code %lu!\n", dwErrorCode
);
217 SetLastError(dwErrorCode
);
218 return (dwErrorCode
== ERROR_SUCCESS
);
222 SetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJobInfo
, DWORD Command
)
229 SetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJobInfo
, DWORD Command
)
232 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
233 WINSPOOL_JOB_CONTAINER JobContainer
;
237 dwErrorCode
= ERROR_INVALID_HANDLE
;
241 // pJobContainer->JobInfo is a union of pointers, so we can just set any element to our BYTE pointer.
242 JobContainer
.Level
= Level
;
243 JobContainer
.JobInfo
.Level1
= (WINSPOOL_JOB_INFO_1
*)pJobInfo
;
248 dwErrorCode
= _RpcSetJob(pHandle
->hPrinter
, JobId
, &JobContainer
, Command
);
250 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
252 dwErrorCode
= RpcExceptionCode();
253 ERR("_RpcSetJob failed with exception code %lu!\n", dwErrorCode
);
258 SetLastError(dwErrorCode
);
259 return (dwErrorCode
== ERROR_SUCCESS
);