Fix copying of structure values in OpenPrinterA
[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", wszStringBinding, 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 DEVMODEW wDevMode;
169 PWSTR pwszPrinterName = NULL;
170 PWSTR pwszDatatype = NULL;
171 PRINTER_DEFAULTSW wDefault = { 0 };
172 size_t StringLength;
173
174 if (pPrinterName)
175 {
176 // Convert pPrinterName to a Unicode string pwszPrinterName
177 StringLength = strlen(pPrinterName) + 1;
178
179 pwszPrinterName = HeapAlloc(GetProcessHeap(), 0, StringLength * sizeof(WCHAR));
180 if (!pwszPrinterName)
181 {
182 ERR("HeapAlloc failed for pwszPrinterName with last error %u!\n", GetLastError());
183 goto Cleanup;
184 }
185
186 MultiByteToWideChar(CP_ACP, 0, pPrinterName, -1, pwszPrinterName, StringLength);
187 }
188
189 if (pDefault)
190 {
191 wDefault.DesiredAccess = pDefault->DesiredAccess;
192
193 if (pDefault->pDatatype)
194 {
195 // Convert pDefault->pDatatype to a Unicode string pwszDatatype that later becomes wDefault.pDatatype
196 StringLength = strlen(pDefault->pDatatype) + 1;
197
198 pwszDatatype = HeapAlloc(GetProcessHeap(), 0, StringLength * sizeof(WCHAR));
199 if (!pwszDatatype)
200 {
201 ERR("HeapAlloc failed for pwszDatatype with last error %u!\n", GetLastError());
202 goto Cleanup;
203 }
204
205 MultiByteToWideChar(CP_ACP, 0, pDefault->pDatatype, -1, pwszDatatype, StringLength);
206 wDefault.pDatatype = pwszDatatype;
207 }
208
209 if (pDefault->pDevMode)
210 {
211 // Fixed size strings, so no additional memory needs to be allocated
212 MultiByteToWideChar(CP_ACP, 0, pDefault->pDevMode->dmDeviceName, -1, wDevMode.dmDeviceName, sizeof(wDevMode.dmDeviceName) / sizeof(WCHAR));
213 MultiByteToWideChar(CP_ACP, 0, pDefault->pDevMode->dmFormName, -1, wDevMode.dmFormName, sizeof(wDevMode.dmFormName) / sizeof(WCHAR));
214
215 // Use CopyMemory to copy over several structure values in one step
216 CopyMemory(&wDevMode.dmSpecVersion, &pDefault->pDevMode->dmSpecVersion, (ULONG_PTR)&wDevMode.dmCollate - (ULONG_PTR)&wDevMode.dmSpecVersion + sizeof(wDevMode.dmCollate));
217 CopyMemory(&wDevMode.dmLogPixels, &pDefault->pDevMode->dmLogPixels, (ULONG_PTR)&wDevMode.dmPanningHeight - (ULONG_PTR)&wDevMode.dmLogPixels + sizeof(wDevMode.dmPanningHeight));
218
219 wDefault.pDevMode = &wDevMode;
220 }
221 }
222
223 ReturnValue = OpenPrinterW(pwszPrinterName, phPrinter, &wDefault);
224
225 Cleanup:
226 if (pwszPrinterName)
227 HeapFree(GetProcessHeap(), 0, pwszPrinterName);
228
229 if (pwszDatatype)
230 HeapFree(GetProcessHeap(), 0, pwszDatatype);
231
232 return ReturnValue;
233 }
234
235 BOOL WINAPI
236 OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault)
237 {
238 BOOL ReturnValue = FALSE;
239 DWORD ErrorCode;
240 PWSTR pDatatype = NULL;
241 WINSPOOL_DEVMODE_CONTAINER DevModeContainer;
242 WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer = NULL;
243 ACCESS_MASK AccessRequired = 0;
244
245 // Prepare the additional parameters in the format required by _RpcOpenPrinter
246 if (pDefault)
247 {
248 pDatatype = pDefault->pDatatype;
249 DevModeContainer.cbBuf = sizeof(DEVMODEW);
250 DevModeContainer.pDevMode = (BYTE*)pDefault->pDevMode;
251 pDevModeContainer = &DevModeContainer;
252 AccessRequired = pDefault->DesiredAccess;
253 }
254
255 // Do the RPC call
256 RpcTryExcept
257 {
258 ErrorCode = _RpcOpenPrinter(pPrinterName, phPrinter, pDatatype, pDevModeContainer, AccessRequired);
259 if (ErrorCode)
260 {
261 ERR("_RpcOpenPrinter failed with error %u!\n", ErrorCode);
262 }
263
264 ReturnValue = (ErrorCode == ERROR_SUCCESS);
265 }
266 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
267 {
268 ERR("_RpcOpenPrinter failed with exception code %u!\n", RpcExceptionCode());
269 }
270 RpcEndExcept;
271
272 return ReturnValue;
273 }
274
275 DWORD WINAPI
276 StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
277 {
278 return 0;
279 }
280
281 BOOL WINAPI
282 StartPagePrinter(HANDLE hPrinter)
283 {
284 return FALSE;
285 }
286
287 BOOL WINAPI
288 WritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten)
289 {
290 return FALSE;
291 }
292
293 BOOL WINAPI
294 XcvDataW(HANDLE hXcv, PCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus)
295 {
296 return FALSE;
297 }