[WINSPOOL]
[reactos.git] / reactos / win32ss / printing / base / winspool / main.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: Main functions
5 * COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 handle_t __RPC_USER
11 WINSPOOL_HANDLE_bind(WINSPOOL_HANDLE wszName)
12 {
13 handle_t hBinding;
14 PWSTR wszStringBinding;
15 RPC_STATUS Status;
16
17 // Get us a string binding handle from the supplied connection information
18 Status = RpcStringBindingComposeW(NULL, L"ncacn_np", wszName, L"\\pipe\\spoolss", NULL, &wszStringBinding);
19 if (Status != RPC_S_OK)
20 {
21 ERR("RpcStringBindingComposeW failed with status %u!\n", Status);
22 return NULL;
23 }
24
25 // Get a handle_t binding handle from the string binding handle
26 Status = RpcBindingFromStringBindingW(wszStringBinding, &hBinding);
27 if (Status != RPC_S_OK)
28 {
29 ERR("RpcBindingFromStringBindingW failed with status %u!\n", Status);
30 return NULL;
31 }
32
33 // Free the string binding handle
34 Status = RpcStringFreeW(&wszStringBinding);
35 if (Status != RPC_S_OK)
36 {
37 ERR("RpcStringFreeW failed with status %u!\n", Status);
38 return NULL;
39 }
40
41 return hBinding;
42 }
43
44 void __RPC_USER
45 WINSPOOL_HANDLE_unbind(WINSPOOL_HANDLE wszName, handle_t hBinding)
46 {
47 RPC_STATUS Status;
48
49 Status = RpcBindingFree(&hBinding);
50 if (Status != RPC_S_OK)
51 {
52 ERR("RpcBindingFree failed with status %u!\n", Status);
53 }
54 }
55
56 void __RPC_FAR* __RPC_USER
57 midl_user_allocate(SIZE_T len)
58 {
59 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
60 }
61
62 void __RPC_USER
63 midl_user_free(void __RPC_FAR* ptr)
64 {
65 HeapFree(GetProcessHeap(), 0, ptr);
66 }
67
68 BOOL WINAPI
69 ClosePrinter(HANDLE hPrinter)
70 {
71 return FALSE;
72 }
73
74 DWORD WINAPI
75 DeviceCapabilitiesA(LPCSTR pDevice, LPCSTR pPort, WORD fwCapability, LPSTR pOutput, const DEVMODEA* pDevMode)
76 {
77 return 0;
78 }
79
80 DWORD WINAPI
81 DeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort, WORD fwCapability, LPWSTR pOutput, const DEVMODEW* pDevMode)
82 {
83 return 0;
84 }
85
86 LONG WINAPI
87 DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput, DWORD fMode)
88 {
89 return 0;
90 }
91
92 LONG WINAPI
93 DocumentPropertiesW(HWND hWnd, HANDLE hPrinter, LPWSTR pDeviceName, PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput, DWORD fMode)
94 {
95 return 0;
96 }
97
98 BOOL WINAPI
99 EndDocPrinter(HANDLE hPrinter)
100 {
101 return FALSE;
102 }
103
104 BOOL WINAPI
105 EndPagePrinter(HANDLE hPrinter)
106 {
107 return FALSE;
108 }
109
110 BOOL WINAPI
111 EnumPrintersA(DWORD Flags, LPSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
112 {
113 return FALSE;
114 }
115
116 BOOL WINAPI
117 EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
118 {
119 return FALSE;
120 }
121
122 BOOL WINAPI
123 GetDefaultPrinterA(LPSTR pszBuffer, LPDWORD pcchBuffer)
124 {
125 return FALSE;
126 }
127
128 BOOL WINAPI
129 GetDefaultPrinterW(LPWSTR pszBuffer, LPDWORD pcchBuffer)
130 {
131 return FALSE;
132 }
133
134 BOOL WINAPI
135 GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded)
136 {
137 return FALSE;
138 }
139
140 BOOL WINAPI
141 GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
142 {
143 return FALSE;
144 }
145
146 BOOL WINAPI
147 GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
148 {
149 return FALSE;
150 }
151
152 BOOL WINAPI
153 GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded)
154 {
155 return FALSE;
156 }
157
158 BOOL WINAPI
159 GetPrintProcessorDirectoryW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded)
160 {
161 return FALSE;
162 }
163
164 BOOL WINAPI
165 OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefault)
166 {
167 BOOL ReturnValue = FALSE;
168 PWSTR pwszPrinterName = NULL;
169 PWSTR pwszDatatype = NULL;
170 PRINTER_DEFAULTSW wDefault = { 0 };
171 size_t StringLength;
172
173 if (pPrinterName)
174 {
175 // Convert pPrinterName to a Unicode string pwszPrinterName
176 StringLength = strlen(pPrinterName) + 1;
177
178 pwszPrinterName = HeapAlloc(GetProcessHeap(), 0, StringLength * sizeof(WCHAR));
179 if (!pwszPrinterName)
180 {
181 ERR("HeapAlloc failed for pwszPrinterName with last error %u!\n", GetLastError());
182 goto Cleanup;
183 }
184
185 MultiByteToWideChar(CP_ACP, 0, pPrinterName, -1, pwszPrinterName, StringLength);
186 }
187
188 if (pDefault)
189 {
190 wDefault.DesiredAccess = pDefault->DesiredAccess;
191
192 if (pDefault->pDatatype)
193 {
194 // Convert pDefault->pDatatype to a Unicode string pwszDatatype that later becomes wDefault.pDatatype
195 StringLength = strlen(pDefault->pDatatype) + 1;
196
197 pwszDatatype = HeapAlloc(GetProcessHeap(), 0, StringLength * sizeof(WCHAR));
198 if (!pwszDatatype)
199 {
200 ERR("HeapAlloc failed for pwszDatatype with last error %u!\n", GetLastError());
201 goto Cleanup;
202 }
203
204 MultiByteToWideChar(CP_ACP, 0, pDefault->pDatatype, -1, pwszDatatype, StringLength);
205 wDefault.pDatatype = pwszDatatype;
206 }
207
208 if (pDefault->pDevMode)
209 wDefault.pDevMode = GdiConvertToDevmodeW(pDefault->pDevMode);
210 }
211
212 ReturnValue = OpenPrinterW(pwszPrinterName, phPrinter, &wDefault);
213
214 Cleanup:
215 if (wDefault.pDevMode)
216 HeapFree(GetProcessHeap(), 0, wDefault.pDevMode);
217
218 if (pwszPrinterName)
219 HeapFree(GetProcessHeap(), 0, pwszPrinterName);
220
221 if (pwszDatatype)
222 HeapFree(GetProcessHeap(), 0, pwszDatatype);
223
224 return ReturnValue;
225 }
226
227 BOOL WINAPI
228 OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault)
229 {
230 BOOL ReturnValue = FALSE;
231 DWORD ErrorCode;
232 PWSTR pDatatype = NULL;
233 WINSPOOL_DEVMODE_CONTAINER DevModeContainer;
234 WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer = NULL;
235 ACCESS_MASK AccessRequired = 0;
236
237 // Prepare the additional parameters in the format required by _RpcOpenPrinter
238 if (pDefault)
239 {
240 pDatatype = pDefault->pDatatype;
241 DevModeContainer.cbBuf = sizeof(DEVMODEW);
242 DevModeContainer.pDevMode = (BYTE*)pDefault->pDevMode;
243 pDevModeContainer = &DevModeContainer;
244 AccessRequired = pDefault->DesiredAccess;
245 }
246
247 // Do the RPC call
248 RpcTryExcept
249 {
250 ErrorCode = _RpcOpenPrinter(pPrinterName, phPrinter, pDatatype, pDevModeContainer, AccessRequired);
251 if (ErrorCode)
252 {
253 ERR("_RpcOpenPrinter failed with error %u!\n", ErrorCode);
254 }
255
256 ReturnValue = (ErrorCode == ERROR_SUCCESS);
257 }
258 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
259 {
260 ERR("_RpcOpenPrinter failed with exception code %u!\n", RpcExceptionCode());
261 }
262 RpcEndExcept;
263
264 return ReturnValue;
265 }
266
267 BOOL WINAPI
268 SpoolerInit()
269 {
270 BOOL ReturnValue = FALSE;
271 DWORD ErrorCode;
272
273 // Nothing to initialize here yet, but pass this call to the Spool Service as well.
274 RpcTryExcept
275 {
276 ErrorCode = _RpcSpoolerInit();
277 if (ErrorCode)
278 {
279 ERR("_RpcSpoolerInit failed with error %u!\n", ErrorCode);
280 }
281
282 ReturnValue = (ErrorCode == ERROR_SUCCESS);
283 }
284 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
285 {
286 ERR("_RpcSpoolerInit failed with exception code %u!\n", RpcExceptionCode());
287 }
288 RpcEndExcept;
289
290 return ReturnValue;
291 }
292
293 DWORD WINAPI
294 StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
295 {
296 return 0;
297 }
298
299 BOOL WINAPI
300 StartPagePrinter(HANDLE hPrinter)
301 {
302 return FALSE;
303 }
304
305 BOOL WINAPI
306 WritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten)
307 {
308 return FALSE;
309 }
310
311 BOOL WINAPI
312 XcvDataW(HANDLE hXcv, PCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus)
313 {
314 return FALSE;
315 }