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