[LOCALSPL]
[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-2016 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 ERR("HeapAlloc failed for pwszName with last error %lu!\n", GetLastError());
133 goto Cleanup;
134 }
135
136 MultiByteToWideChar(CP_ACP, 0, pName, -1, pwszName, cch + 1);
137 }
138
139 if (pEnvironment)
140 {
141 // Convert pEnvironment to a Unicode string pwszEnvironment.
142 cch = strlen(pEnvironment);
143
144 pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
145 if (!pwszEnvironment)
146 {
147 ERR("HeapAlloc failed for pwszEnvironment with last error %lu!\n", GetLastError());
148 goto Cleanup;
149 }
150
151 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1);
152 }
153
154 if (cbBuf && pPrintProcessorInfo)
155 {
156 // Allocate a temporary buffer for the Unicode result.
157 // We can just go with cbBuf here. The user should have set it based on pcbNeeded returned in a previous call and our
158 // pcbNeeded is the same for the A and W functions.
159 pwszPrintProcessorInfo = HeapAlloc(hProcessHeap, 0, cbBuf);
160 if (!pwszPrintProcessorInfo)
161 {
162 ERR("HeapAlloc failed for pwszPrintProcessorInfo with last error %lu!\n", GetLastError());
163 goto Cleanup;
164 }
165 }
166
167 bReturnValue = GetPrintProcessorDirectoryW(pwszName, pwszEnvironment, Level, (PBYTE)pwszPrintProcessorInfo, cbBuf, pcbNeeded);
168
169 if (bReturnValue)
170 {
171 // Convert pwszPrintProcessorInfo to an ANSI string pPrintProcessorInfo.
172 WideCharToMultiByte(CP_ACP, 0, pwszPrintProcessorInfo, -1, (PSTR)pPrintProcessorInfo, cbBuf, NULL, NULL);
173 }
174
175 Cleanup:
176 if (pwszName)
177 HeapFree(hProcessHeap, 0, pwszName);
178
179 if (pwszEnvironment)
180 HeapFree(hProcessHeap, 0, pwszEnvironment);
181
182 if (pwszPrintProcessorInfo)
183 HeapFree(hProcessHeap, 0, pwszPrintProcessorInfo);
184
185 return bReturnValue;
186 }
187
188 BOOL WINAPI
189 GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
190 {
191 DWORD dwErrorCode;
192
193 // Sanity checks
194 if (Level != 1)
195 {
196 dwErrorCode = ERROR_INVALID_LEVEL;
197 goto Cleanup;
198 }
199
200 // Choose our current environment if the caller didn't give any.
201 if (!pEnvironment)
202 pEnvironment = (PWSTR)wszCurrentEnvironment;
203
204 // Do the RPC call
205 RpcTryExcept
206 {
207 dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
208 }
209 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
210 {
211 dwErrorCode = RpcExceptionCode();
212 }
213 RpcEndExcept;
214
215 Cleanup:
216 SetLastError(dwErrorCode);
217 return (dwErrorCode == ERROR_SUCCESS);
218 }