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