ReactOS 0.4.16-dev-401-g45b008d
printprocessors.c
Go to the documentation of this file.
1/*
2* PROJECT: ReactOS Spooler API
3* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4* PURPOSE: Functions related to Print Processors
5* COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
6*/
7
8#include "precomp.h"
10#include <prtprocenv.h>
11
13AddPrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPathName, PSTR pPrintProcessorName)
14{
15 UNICODE_STRING NameW, EnvW, PathW, ProcessorW;
16 BOOL Ret;
17
18 TRACE("AddPrintProcessorA(%s, %s, %s, %s)\n", pName, pEnvironment, pPathName, pPrintProcessorName);
19
20 AsciiToUnicode(&NameW, pName);
21 AsciiToUnicode(&EnvW, pEnvironment);
22 AsciiToUnicode(&PathW, pPathName);
23 AsciiToUnicode(&ProcessorW, pPrintProcessorName);
24
25 Ret = AddPrintProcessorW(NameW.Buffer, EnvW.Buffer, PathW.Buffer, ProcessorW.Buffer);
26
27 RtlFreeUnicodeString(&ProcessorW);
31
32 return Ret;
33}
34
36AddPrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPathName, PWSTR pPrintProcessorName)
37{
38 DWORD dwErrorCode;
39
40 TRACE("AddPrintProcessorW(%S, %S, %S, %S)\n", pName, pEnvironment, pPathName, pPrintProcessorName);
41
43 {
44 dwErrorCode = _RpcAddPrintProcessor( pName, pEnvironment, pPathName, pPrintProcessorName );
45 }
47 {
48 dwErrorCode = RpcExceptionCode();
49 ERR("_RpcPrintProcessor failed with exception code %lu!\n", dwErrorCode);
50 }
52
53 SetLastError(dwErrorCode);
54 return (dwErrorCode == ERROR_SUCCESS);
55}
56
58DeletePrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPrintProcessorName)
59{
60 UNICODE_STRING NameW, EnvW, ProcessorW;
61 BOOL Ret;
62
63 TRACE("DeletePrintProcessorA(%s, %s, %s)\n", pName, pEnvironment, pPrintProcessorName);
64
65 AsciiToUnicode(&NameW, pName);
66 AsciiToUnicode(&EnvW, pEnvironment);
67 AsciiToUnicode(&ProcessorW, pPrintProcessorName);
68
69 Ret = DeletePrintProcessorW(NameW.Buffer, EnvW.Buffer, ProcessorW.Buffer);
70
71 RtlFreeUnicodeString(&ProcessorW);
74
75 return Ret;
76}
77
79DeletePrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPrintProcessorName)
80{
81 DWORD dwErrorCode;
82
83 TRACE("DeletePrintProcessorW(%S, %S, %S)\n", pName, pEnvironment, pPrintProcessorName);
84
86 {
87 dwErrorCode = _RpcDeletePrintProcessor( pName, pEnvironment, pPrintProcessorName );
88 }
90 {
91 dwErrorCode = RpcExceptionCode();
92 ERR("_RpcDeletePrintProcessor failed with exception code %lu!\n", dwErrorCode);
93 }
95
96 SetLastError(dwErrorCode);
97 return (dwErrorCode == ERROR_SUCCESS);
98}
99
101EnumPrintProcessorDatatypesA(PSTR pName, LPSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
102{
103 TRACE("EnumPrintProcessorDatatypesA(%s, %s, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
105 return FALSE;
106}
107
109EnumPrintProcessorDatatypesW(PWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
110{
111 DWORD dwErrorCode;
112
113 TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
114
115 // Sanity checks
116 if (Level != 1)
117 {
118 dwErrorCode = ERROR_INVALID_LEVEL;
119 goto Cleanup;
120 }
121
122 // Do the RPC call
124 {
125 dwErrorCode = _RpcEnumPrintProcessorDatatypes(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
126 }
128 {
129 dwErrorCode = RpcExceptionCode();
130 ERR("_RpcEnumPrintProcessorDatatypes failed with exception code %lu!\n", dwErrorCode);
131 }
133
134 if (dwErrorCode == ERROR_SUCCESS)
135 {
136 // Replace relative offset addresses in the output by absolute pointers.
138 }
139
140Cleanup:
141 SetLastError(dwErrorCode);
142 return (dwErrorCode == ERROR_SUCCESS);
143}
144
146EnumPrintProcessorsA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
147{
148 BOOL res;
149 LPBYTE bufferW = NULL;
150 LPWSTR nameW = NULL;
151 LPWSTR envW = NULL;
152 DWORD needed = 0;
153 DWORD numentries = 0;
154 INT len;
155
156 TRACE("EnumPrintProcessorsA(%s, %s, %d, %p, %d, %p, %p)\n", debugstr_a(pName), debugstr_a(pEnvironment), Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
157
158 /* convert names to unicode */
159 if (pName)
160 {
161 len = MultiByteToWideChar(CP_ACP, 0, pName, -1, NULL, 0);
162 nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
164 }
165 if (pEnvironment)
166 {
167 len = MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, NULL, 0);
168 envW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
169 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, envW, len);
170 }
171
172 /* alloc (userbuffersize*sizeof(WCHAR) and try to enum the monitors */
173 needed = cbBuf * sizeof(WCHAR);
174 if (needed) bufferW = HeapAlloc(GetProcessHeap(), 0, needed);
175 res = EnumPrintProcessorsW(nameW, envW, Level, bufferW, needed, pcbNeeded, pcReturned);
176
178 {
179 if (pcbNeeded) needed = *pcbNeeded;
180 /* HeapReAlloc return NULL, when bufferW was NULL */
181 bufferW = (bufferW) ? HeapReAlloc(GetProcessHeap(), 0, bufferW, needed) :
182 HeapAlloc(GetProcessHeap(), 0, needed);
183
184 /* Try again with the large Buffer */
185 res = EnumPrintProcessorsW(nameW, envW, Level, bufferW, needed, pcbNeeded, pcReturned);
186 }
187 numentries = pcReturned ? *pcReturned : 0;
188 needed = 0;
189
190 if (res)
191 {
192 /* EnumPrintProcessorsW collected all Data. Parse them to calculate ANSI-Size */
193 DWORD index;
194 LPSTR ptr;
197
198 /* First pass: calculate the size for all Entries */
199 ppiw = (PPRINTPROCESSOR_INFO_1W) bufferW;
200 ppia = (PPRINTPROCESSOR_INFO_1A) pPrintProcessorInfo;
201 index = 0;
202 while (index < numentries)
203 {
204 index++;
205 needed += sizeof(PRINTPROCESSOR_INFO_1A);
206 TRACE("%p: parsing #%d (%s)\n", ppiw, index, debugstr_w(ppiw->pName));
207
208 needed += WideCharToMultiByte(CP_ACP, 0, ppiw->pName, -1,
209 NULL, 0, NULL, NULL);
210
211 ppiw = (PPRINTPROCESSOR_INFO_1W) (((LPBYTE)ppiw) + sizeof(PRINTPROCESSOR_INFO_1W));
212 ppia = (PPRINTPROCESSOR_INFO_1A) (((LPBYTE)ppia) + sizeof(PRINTPROCESSOR_INFO_1A));
213 }
214
215 /* check for errors and quit on failure */
216 if (cbBuf < needed)
217 {
219 res = FALSE;
220 goto epp_cleanup;
221 }
222
223 len = numentries * sizeof(PRINTPROCESSOR_INFO_1A); /* room for structs */
224 ptr = (LPSTR) &pPrintProcessorInfo[len]; /* start of strings */
225 cbBuf -= len ; /* free Bytes in the user-Buffer */
226 ppiw = (PPRINTPROCESSOR_INFO_1W) bufferW;
227 ppia = (PPRINTPROCESSOR_INFO_1A) pPrintProcessorInfo;
228 index = 0;
229 /* Second Pass: Fill the User Buffer (if we have one) */
230 while ((index < numentries) && pPrintProcessorInfo)
231 {
232 index++;
233 TRACE("%p: writing PRINTPROCESSOR_INFO_1A #%d\n", ppia, index);
234 ppia->pName = ptr;
235 len = WideCharToMultiByte(CP_ACP, 0, ppiw->pName, -1,
236 ptr, cbBuf , NULL, NULL);
237 ptr += len;
238 cbBuf -= len;
239
240 ppiw = (PPRINTPROCESSOR_INFO_1W) (((LPBYTE)ppiw) + sizeof(PRINTPROCESSOR_INFO_1W));
241 ppia = (PPRINTPROCESSOR_INFO_1A) (((LPBYTE)ppia) + sizeof(PRINTPROCESSOR_INFO_1A));
242
243 }
244 }
245epp_cleanup:
246 if (pcbNeeded) *pcbNeeded = needed;
247 if (pcReturned) *pcReturned = (res) ? numentries : 0;
248
250 if (envW) HeapFree(GetProcessHeap(), 0, envW);
251 if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
252
253 TRACE("returning %d with %d (%d byte for %d entries)\n", (res), GetLastError(), needed, numentries);
254
255 return (res);
256
257}
258
260EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
261{
262 DWORD dwErrorCode;
263
264 TRACE("EnumPrintProcessorsW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
265
266 // Choose our current environment if the caller didn't give any.
267 if (!pEnvironment)
268 pEnvironment = (PWSTR)wszCurrentEnvironment;
269
270 // Do the RPC call
272 {
273 dwErrorCode = _RpcEnumPrintProcessors(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
274 }
276 {
277 dwErrorCode = RpcExceptionCode();
278 }
280
281 if (dwErrorCode == ERROR_SUCCESS)
282 {
283 // Replace relative offset addresses in the output by absolute pointers.
285 }
286
287 SetLastError(dwErrorCode);
288 return (dwErrorCode == ERROR_SUCCESS);
289}
290
292GetPrintProcessorDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
293{
294 BOOL bReturnValue = FALSE;
295 DWORD cch;
296 PWSTR pwszName = NULL;
297 PWSTR pwszEnvironment = NULL;
298 PWSTR pwszPrintProcessorInfo = NULL;
299
300 TRACE("GetPrintProcessorDirectoryA(%s, %s, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
301
302 if (pName)
303 {
304 // Convert pName to a Unicode string pwszName.
305 cch = strlen(pName);
306
307 pwszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
308 if (!pwszName)
309 {
311 ERR("HeapAlloc failed!\n");
312 goto Cleanup;
313 }
314
315 MultiByteToWideChar(CP_ACP, 0, pName, -1, pwszName, cch + 1);
316 }
317
318 if (pEnvironment)
319 {
320 // Convert pEnvironment to a Unicode string pwszEnvironment.
321 cch = strlen(pEnvironment);
322
323 pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
324 if (!pwszEnvironment)
325 {
327 ERR("HeapAlloc failed!\n");
328 goto Cleanup;
329 }
330
331 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1);
332 }
333
334 if (cbBuf && pPrintProcessorInfo)
335 {
336 // Allocate a temporary buffer for the Unicode result.
337 // We can just go with cbBuf here. The user should have set it based on pcbNeeded returned in a previous call and our
338 // pcbNeeded is the same for the A and W functions.
339 pwszPrintProcessorInfo = HeapAlloc(hProcessHeap, 0, cbBuf);
340 if (!pwszPrintProcessorInfo)
341 {
343 ERR("HeapAlloc failed!\n");
344 goto Cleanup;
345 }
346 }
347
348 bReturnValue = GetPrintProcessorDirectoryW(pwszName, pwszEnvironment, Level, (PBYTE)pwszPrintProcessorInfo, cbBuf, pcbNeeded);
349
350 if (bReturnValue)
351 {
352 // Convert pwszPrintProcessorInfo to an ANSI string pPrintProcessorInfo.
353 WideCharToMultiByte(CP_ACP, 0, pwszPrintProcessorInfo, -1, (PSTR)pPrintProcessorInfo, cbBuf, NULL, NULL);
354 }
355
356Cleanup:
357 if (pwszName)
358 HeapFree(hProcessHeap, 0, pwszName);
359
360 if (pwszEnvironment)
361 HeapFree(hProcessHeap, 0, pwszEnvironment);
362
363 if (pwszPrintProcessorInfo)
364 HeapFree(hProcessHeap, 0, pwszPrintProcessorInfo);
365
366 return bReturnValue;
367}
368
370GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
371{
372 DWORD dwErrorCode;
373
374 TRACE("GetPrintProcessorDirectoryW(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
375
376 // Sanity checks
377 if (Level != 1)
378 {
379 dwErrorCode = ERROR_INVALID_LEVEL;
380 goto Cleanup;
381 }
382
383 // Choose our current environment if the caller didn't give any.
384 if (!pEnvironment)
385 pEnvironment = (PWSTR)wszCurrentEnvironment;
386
387 // Do the RPC call
389 {
390 dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
391 }
393 {
394 dwErrorCode = RpcExceptionCode();
395 }
397
398Cleanup:
399 SetLastError(dwErrorCode);
400 return (dwErrorCode == ERROR_SUCCESS);
401}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static const WCHAR nameW[]
Definition: main.c:49
#define index(s, c)
Definition: various.h:29
#define ERR(fmt,...)
Definition: precomp.h:57
BOOL WINAPI EnumPrintProcessorDatatypesW(PWSTR pName, PWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
BOOL WINAPI GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
BOOL WINAPI AddPrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPathName, PWSTR pPrintProcessorName)
BOOL WINAPI DeletePrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPrintProcessorName)
BOOL WINAPI EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
DWORD _RpcAddPrintProcessor(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, WCHAR *pPathName, WCHAR *pPrintProcessorName)
DWORD _RpcEnumPrintProcessors(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD Level, BYTE *pPrintProcessorInfo, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned)
DWORD _RpcDeletePrintProcessor(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, WCHAR *pPrintProcessorName)
DWORD _RpcGetPrintProcessorDirectory(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD Level, BYTE *pPrintProcessorDirectory, DWORD cbBuf, DWORD *pcbNeeded)
DWORD _RpcEnumPrintProcessorDatatypes(WINSPOOL_HANDLE pName, WCHAR *pPrintProcessorName, DWORD Level, BYTE *pDatatypes, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned)
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
BOOL WINAPI EnumPrintProcessorDatatypesA(PSTR pName, LPSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
BOOL WINAPI EnumPrintProcessorsA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
BOOL WINAPI DeletePrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPrintProcessorName)
BOOL WINAPI AddPrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPathName, PSTR pPrintProcessorName)
BOOL WINAPI GetPrintProcessorDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLenum GLsizei len
Definition: glext.h:6722
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
HANDLE hProcessHeap
Definition: kbswitch.c:37
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
BOOL WINAPI MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO *pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
Definition: marshalling.c:202
static PVOID ptr
Definition: dispmode.c:27
wstring AsciiToUnicode(const char *AsciiString)
Definition: tools.cpp:220
static LPSTR pName
Definition: security.c:75
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
static const MARSHALLING DatatypesInfo1Marshalling
static const MARSHALLING PrintProcessorInfo1Marshalling
#define RpcEndExcept
Definition: rpc.h:128
#define RpcTryExcept
Definition: rpc.h:126
#define RpcExcept(expr)
Definition: rpc.h:127
#define RpcExceptionCode()
Definition: rpc.h:132
#define TRACE(s)
Definition: solgame.cpp:4
MARSHALLING_INFO pInfo[]
Definition: marshalling.h:26
DWORD cbStructureSize
Definition: marshalling.h:25
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
struct _PRINTPROCESSOR_INFO_1W * PPRINTPROCESSOR_INFO_1W
struct _PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1W
struct _PRINTPROCESSOR_INFO_1A * PPRINTPROCESSOR_INFO_1A
struct _PRINTPROCESSOR_INFO_1A PRINTPROCESSOR_INFO_1A
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184