406297de6f021c4fa380385ae9143eab9f1b1da2
[reactos.git] / win32ss / printing / base / winspool / printprocessors.c
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-2017 Colin Finck (colin@reactos.org)
6 */
7
8 #include "precomp.h"
9 #include <prtprocenv.h>
10
11 static void
12 _MarshallUpDatatypesInfo(PDATATYPES_INFO_1W* ppDatatypesInfo1)
13 {
14 // Replace relative offset addresses in the output by absolute pointers.
15 PDATATYPES_INFO_1W pDatatypesInfo1 = *ppDatatypesInfo1;
16 pDatatypesInfo1->pName = (PWSTR)((ULONG_PTR)pDatatypesInfo1->pName + (ULONG_PTR)pDatatypesInfo1);
17 *ppDatatypesInfo1 += sizeof(DATATYPES_INFO_1W);
18 }
19
20 static void
21 _MarshallUpPrintProcessorInfo(PPRINTPROCESSOR_INFO_1W* ppPrintProcessorInfo1)
22 {
23 // Replace relative offset addresses in the output by absolute pointers.
24 PPRINTPROCESSOR_INFO_1W pPrintProcessorInfo1 = *ppPrintProcessorInfo1;
25 pPrintProcessorInfo1->pName = (PWSTR)((ULONG_PTR)pPrintProcessorInfo1->pName + (ULONG_PTR)pPrintProcessorInfo1);
26 *ppPrintProcessorInfo1 += sizeof(PRINTPROCESSOR_INFO_1W);
27 }
28
29 BOOL WINAPI
30 AddPrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPathName, PSTR pPrintProcessorName)
31 {
32 TRACE("AddPrintProcessorA(%s, %s, %s, %s)\n", pName, pEnvironment, pPathName, pPrintProcessorName);
33 UNIMPLEMENTED;
34 return FALSE;
35 }
36
37 BOOL WINAPI
38 AddPrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPathName, PWSTR pPrintProcessorName)
39 {
40 TRACE("AddPrintProcessorW(%S, %S, %S, %S)\n", pName, pEnvironment, pPathName, pPrintProcessorName);
41 UNIMPLEMENTED;
42 return FALSE;
43 }
44
45 BOOL WINAPI
46 DeletePrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPrintProcessorName)
47 {
48 TRACE("DeletePrintProcessorA(%s, %s, %s)\n", pName, pEnvironment, pPrintProcessorName);
49 UNIMPLEMENTED;
50 return FALSE;
51 }
52
53 BOOL WINAPI
54 DeletePrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPrintProcessorName)
55 {
56 TRACE("DeletePrintProcessorW(%S, %S, %S)\n", pName, pEnvironment, pPrintProcessorName);
57 UNIMPLEMENTED;
58 return FALSE;
59 }
60
61 BOOL WINAPI
62 EnumPrintProcessorDatatypesA(PSTR pName, LPSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
63 {
64 TRACE("EnumPrintProcessorDatatypesA(%s, %s, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
65 UNIMPLEMENTED;
66 return FALSE;
67 }
68
69 BOOL WINAPI
70 EnumPrintProcessorDatatypesW(PWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
71 {
72 DWORD dwErrorCode;
73
74 TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
75
76 // Sanity checks
77 if (Level != 1)
78 {
79 dwErrorCode = ERROR_INVALID_LEVEL;
80 goto Cleanup;
81 }
82
83 // Do the RPC call
84 RpcTryExcept
85 {
86 dwErrorCode = _RpcEnumPrintProcessorDatatypes(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
87 }
88 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
89 {
90 dwErrorCode = RpcExceptionCode();
91 ERR("_RpcEnumPrintProcessorDatatypes failed with exception code %lu!\n", dwErrorCode);
92 }
93 RpcEndExcept;
94
95 if (dwErrorCode == ERROR_SUCCESS)
96 {
97 DWORD i;
98 PDATATYPES_INFO_1W p = (PDATATYPES_INFO_1W)pDatatypes;
99
100 for (i = 0; i < *pcReturned; i++)
101 _MarshallUpDatatypesInfo(&p);
102 }
103
104 Cleanup:
105 SetLastError(dwErrorCode);
106 return (dwErrorCode == ERROR_SUCCESS);
107 }
108
109 BOOL WINAPI
110 EnumPrintProcessorsA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
111 {
112 TRACE("EnumPrintProcessorsA(%s, %s, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
113 UNIMPLEMENTED;
114 return FALSE;
115 }
116
117 BOOL WINAPI
118 EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
119 {
120 DWORD dwErrorCode;
121
122 TRACE("EnumPrintProcessorsW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
123
124 // Choose our current environment if the caller didn't give any.
125 if (!pEnvironment)
126 pEnvironment = (PWSTR)wszCurrentEnvironment;
127
128 // Do the RPC call
129 RpcTryExcept
130 {
131 dwErrorCode = _RpcEnumPrintProcessors(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
132 }
133 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
134 {
135 dwErrorCode = RpcExceptionCode();
136 }
137 RpcEndExcept;
138
139 if (dwErrorCode == ERROR_SUCCESS)
140 {
141 DWORD i;
142 PPRINTPROCESSOR_INFO_1W p = (PPRINTPROCESSOR_INFO_1W)pPrintProcessorInfo;
143
144 for (i = 0; i < *pcReturned; i++)
145 _MarshallUpPrintProcessorInfo(&p);
146 }
147
148 SetLastError(dwErrorCode);
149 return (dwErrorCode == ERROR_SUCCESS);
150 }
151
152 BOOL WINAPI
153 GetPrintProcessorDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
154 {
155 BOOL bReturnValue = FALSE;
156 DWORD cch;
157 PWSTR pwszName = NULL;
158 PWSTR pwszEnvironment = NULL;
159 PWSTR pwszPrintProcessorInfo = NULL;
160
161 TRACE("GetPrintProcessorDirectoryA(%s, %s, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
162
163 if (pName)
164 {
165 // Convert pName to a Unicode string pwszName.
166 cch = strlen(pName);
167
168 pwszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
169 if (!pwszName)
170 {
171 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
172 ERR("HeapAlloc failed!\n");
173 goto Cleanup;
174 }
175
176 MultiByteToWideChar(CP_ACP, 0, pName, -1, pwszName, cch + 1);
177 }
178
179 if (pEnvironment)
180 {
181 // Convert pEnvironment to a Unicode string pwszEnvironment.
182 cch = strlen(pEnvironment);
183
184 pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
185 if (!pwszEnvironment)
186 {
187 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
188 ERR("HeapAlloc failed!\n");
189 goto Cleanup;
190 }
191
192 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1);
193 }
194
195 if (cbBuf && pPrintProcessorInfo)
196 {
197 // Allocate a temporary buffer for the Unicode result.
198 // We can just go with cbBuf here. The user should have set it based on pcbNeeded returned in a previous call and our
199 // pcbNeeded is the same for the A and W functions.
200 pwszPrintProcessorInfo = HeapAlloc(hProcessHeap, 0, cbBuf);
201 if (!pwszPrintProcessorInfo)
202 {
203 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
204 ERR("HeapAlloc failed!\n");
205 goto Cleanup;
206 }
207 }
208
209 bReturnValue = GetPrintProcessorDirectoryW(pwszName, pwszEnvironment, Level, (PBYTE)pwszPrintProcessorInfo, cbBuf, pcbNeeded);
210
211 if (bReturnValue)
212 {
213 // Convert pwszPrintProcessorInfo to an ANSI string pPrintProcessorInfo.
214 WideCharToMultiByte(CP_ACP, 0, pwszPrintProcessorInfo, -1, (PSTR)pPrintProcessorInfo, cbBuf, NULL, NULL);
215 }
216
217 Cleanup:
218 if (pwszName)
219 HeapFree(hProcessHeap, 0, pwszName);
220
221 if (pwszEnvironment)
222 HeapFree(hProcessHeap, 0, pwszEnvironment);
223
224 if (pwszPrintProcessorInfo)
225 HeapFree(hProcessHeap, 0, pwszPrintProcessorInfo);
226
227 return bReturnValue;
228 }
229
230 BOOL WINAPI
231 GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
232 {
233 DWORD dwErrorCode;
234
235 TRACE("GetPrintProcessorDirectoryW(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
236
237 // Sanity checks
238 if (Level != 1)
239 {
240 dwErrorCode = ERROR_INVALID_LEVEL;
241 goto Cleanup;
242 }
243
244 // Choose our current environment if the caller didn't give any.
245 if (!pEnvironment)
246 pEnvironment = (PWSTR)wszCurrentEnvironment;
247
248 // Do the RPC call
249 RpcTryExcept
250 {
251 dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
252 }
253 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
254 {
255 dwErrorCode = RpcExceptionCode();
256 }
257 RpcEndExcept;
258
259 Cleanup:
260 SetLastError(dwErrorCode);
261 return (dwErrorCode == ERROR_SUCCESS);
262 }