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
;
68 dwErrorCode
= _RpcAddJob(hPrinter
, Level
, pData
, cbBuf
, pcbNeeded
);
70 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
72 dwErrorCode
= RpcExceptionCode();
73 ERR("_RpcAddJob failed with exception code %lu!\n", dwErrorCode
);
77 if (dwErrorCode
== ERROR_SUCCESS
)
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
);
84 SetLastError(dwErrorCode
);
85 return (dwErrorCode
== ERROR_SUCCESS
);
89 EnumJobsA(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
96 EnumJobsW(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
105 dwErrorCode
= _RpcEnumJobs(hPrinter
, FirstJob
, NoJobs
, Level
, pJob
, cbBuf
, pcbNeeded
, pcReturned
);
107 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
109 dwErrorCode
= RpcExceptionCode();
110 ERR("_RpcEnumJobs failed with exception code %lu!\n", dwErrorCode
);
114 if (dwErrorCode
== ERROR_SUCCESS
)
116 // Replace relative offset addresses in the output by absolute pointers.
117 for (i
= 0; i
< *pcReturned
; i
++)
119 _MarshallUpJobInfo(p
, Level
);
122 p
+= sizeof(JOB_INFO_1W
);
124 p
+= sizeof(JOB_INFO_2W
);
128 SetLastError(dwErrorCode
);
129 return (dwErrorCode
== ERROR_SUCCESS
);
133 GetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
)
140 GetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJob
, DWORD cbBuf
, PDWORD pcbNeeded
)
147 dwErrorCode
= _RpcGetJob(hPrinter
, JobId
, Level
, pJob
, cbBuf
, pcbNeeded
);
149 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
151 dwErrorCode
= RpcExceptionCode();
152 ERR("_RpcGetJob failed with exception code %lu!\n", dwErrorCode
);
156 if (dwErrorCode
== ERROR_SUCCESS
)
158 // Replace relative offset addresses in the output by absolute pointers.
159 _MarshallUpJobInfo(pJob
, Level
);
162 SetLastError(dwErrorCode
);
163 return (dwErrorCode
== ERROR_SUCCESS
);
167 ScheduleJob(HANDLE hPrinter
, DWORD dwJobID
)
174 dwErrorCode
= _RpcScheduleJob(hPrinter
, dwJobID
);
176 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
178 dwErrorCode
= RpcExceptionCode();
179 ERR("_RpcSetJob failed with exception code %lu!\n", dwErrorCode
);
183 SetLastError(dwErrorCode
);
184 return (dwErrorCode
== ERROR_SUCCESS
);
188 SetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJobInfo
, DWORD Command
)
195 SetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
, PBYTE pJobInfo
, DWORD Command
)
198 WINSPOOL_JOB_CONTAINER JobContainer
;
200 // pJobContainer->JobInfo is a union of pointers, so we can just set any element to our BYTE pointer.
201 JobContainer
.Level
= Level
;
202 JobContainer
.JobInfo
.Level1
= (WINSPOOL_JOB_INFO_1
*)pJobInfo
;
207 dwErrorCode
= _RpcSetJob(hPrinter
, JobId
, &JobContainer
, Command
);
209 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
211 dwErrorCode
= RpcExceptionCode();
212 ERR("_RpcSetJob failed with exception code %lu!\n", dwErrorCode
);
216 SetLastError(dwErrorCode
);
217 return (dwErrorCode
== ERROR_SUCCESS
);