ReactOS  0.4.15-dev-1033-gd7d716a
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 
13 AddPrintProcessorA(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);
28  RtlFreeUnicodeString(&PathW);
29  RtlFreeUnicodeString(&EnvW);
30  RtlFreeUnicodeString(&NameW);
31 
32  return Ret;
33 }
34 
36 AddPrintProcessorW(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 
58 DeletePrintProcessorA(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);
72  RtlFreeUnicodeString(&EnvW);
73  RtlFreeUnicodeString(&NameW);
74 
75  return Ret;
76 }
77 
79 DeletePrintProcessorW(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 
100 BOOL WINAPI
101 EnumPrintProcessorDatatypesA(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 
108 BOOL WINAPI
109 EnumPrintProcessorDatatypesW(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  }
132  RpcEndExcept;
133 
134  if (dwErrorCode == ERROR_SUCCESS)
135  {
136  // Replace relative offset addresses in the output by absolute pointers.
138  }
139 
140 Cleanup:
141  SetLastError(dwErrorCode);
142  return (dwErrorCode == ERROR_SUCCESS);
143 }
144 
145 BOOL WINAPI
146 EnumPrintProcessorsA(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  }
245 epp_cleanup:
246  if (pcbNeeded) *pcbNeeded = needed;
247  if (pcReturned) *pcReturned = (res) ? numentries : 0;
248 
249  if (nameW) HeapFree(GetProcessHeap(), 0, nameW);
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 
259 BOOL WINAPI
260 EnumPrintProcessorsW(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  }
279  RpcEndExcept;
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 
291 BOOL WINAPI
292 GetPrintProcessorDirectoryA(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 
356 Cleanup:
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 
369 BOOL WINAPI
370 GetPrintProcessorDirectoryW(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  }
396  RpcEndExcept;
397 
398 Cleanup:
399  SetLastError(dwErrorCode);
400  return (dwErrorCode == ERROR_SUCCESS);
401 }
BOOL WINAPI EnumPrintProcessorsA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
DWORD cbStructureSize
Definition: marshalling.h:25
BOOL WINAPI DeletePrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPrintProcessorName)
MARSHALLING_INFO pInfo[]
Definition: marshalling.h:26
#define RpcEndExcept
Definition: rpc.h:128
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:111
struct _PRINTPROCESSOR_INFO_1W * PPRINTPROCESSOR_INFO_1W
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
#define CP_ACP
Definition: compat.h:109
BOOL WINAPI DeletePrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPrintProcessorName)
struct _PRINTPROCESSOR_INFO_1A * PPRINTPROCESSOR_INFO_1A
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
char * LPSTR
Definition: xmlstorage.h:182
int32_t INT
Definition: typedefs.h:58
struct _PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1W
static const MARSHALLING DatatypesInfo1Marshalling
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define debugstr_w
Definition: kernel32.h:32
BOOL WINAPI GetPrintProcessorDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
static PVOID ptr
Definition: dispmode.c:27
#define RpcTryExcept
Definition: rpc.h:126
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
smooth NULL
Definition: ftsmooth.c:416
DWORD _RpcAddPrintProcessor(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, WCHAR *pPathName, WCHAR *pPrintProcessorName)
GLuint index
Definition: glext.h:6031
DWORD _RpcEnumPrintProcessorDatatypes(WINSPOOL_HANDLE pName, WCHAR *pPrintProcessorName, DWORD Level, BYTE *pDatatypes, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned)
wstring AsciiToUnicode(const char *AsciiString)
Definition: tools.cpp:220
static const WCHAR nameW[]
Definition: main.c:46
#define RpcExceptionCode()
Definition: rpc.h:132
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:500
#define index(s, c)
Definition: various.h:29
GLenum GLsizei len
Definition: glext.h:6722
BOOL WINAPI AddPrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPathName, PWSTR pPrintProcessorName)
static const WCHAR Cleanup[]
Definition: register.c:80
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)
static const MARSHALLING PrintProcessorInfo1Marshalling
#define ERR(fmt,...)
Definition: debug.h:110
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
struct _PRINTPROCESSOR_INFO_1A PRINTPROCESSOR_INFO_1A
#define HeapReAlloc
Definition: compat.h:482
signed char * PSTR
Definition: retypes.h:7
DWORD * PDWORD
Definition: pedump.c:68
#define MultiByteToWideChar
Definition: compat.h:110
GLuint res
Definition: glext.h:9613
BOOL WINAPI EnumPrintProcessorDatatypesW(PWSTR pName, PWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
BOOL WINAPI AddPrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPathName, PSTR pPrintProcessorName)
#define UNIMPLEMENTED
Definition: debug.h:115
DWORD _RpcGetPrintProcessorDirectory(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD Level, BYTE *pPrintProcessorDirectory, DWORD cbBuf, DWORD *pcbNeeded)
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
BOOL WINAPI EnumPrintProcessorDatatypesA(PSTR pName, LPSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BYTE * PBYTE
Definition: pedump.c:66
#define HeapFree(x, y, z)
Definition: compat.h:483
BOOL WINAPI EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
#define RpcExcept(expr)
Definition: rpc.h:127
BOOL WINAPI MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO *pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
Definition: marshalling.c:202
HANDLE hProcessHeap
Definition: kbswitch.c:25
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10