1 /*
2 * Routing for Spooler-Service helper DLL
3 *
4 * Copyright 2006-2009 Detlef Riekenberg
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winreg.h"
27
28 #include "wingdi.h"
29 #include "winspool.h"
30 #include "ddk/winsplp.h"
31 #include "spoolss.h"
32
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(spoolss);
36
37 /* ################################ */
38
39 #define MAX_BACKEND 3
40
41 typedef struct {
42 /* PRINTPROVIDOR functions */
43 DWORD (WINAPI *fpOpenPrinter)(LPWSTR, HANDLE *, LPPRINTER_DEFAULTSW);
44 DWORD (WINAPI *fpSetJob)(HANDLE, DWORD, DWORD, LPBYTE, DWORD);
45 DWORD (WINAPI *fpGetJob)(HANDLE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD);
46 DWORD (WINAPI *fpEnumJobs)(HANDLE, DWORD, DWORD, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
47 HANDLE (WINAPI *fpAddPrinter)(LPWSTR, DWORD, LPBYTE);
48 DWORD (WINAPI *fpDeletePrinter)(HANDLE);
49 DWORD (WINAPI *fpSetPrinter)(HANDLE, DWORD, LPBYTE, DWORD);
50 DWORD (WINAPI *fpGetPrinter)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
51 DWORD (WINAPI *fpEnumPrinters)(DWORD, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
52 DWORD (WINAPI *fpAddPrinterDriver)(LPWSTR, DWORD, LPBYTE);
53 DWORD (WINAPI *fpEnumPrinterDrivers)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
54 DWORD (WINAPI *fpGetPrinterDriver)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
55 DWORD (WINAPI *fpGetPrinterDriverDirectory)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
56 DWORD (WINAPI *fpDeletePrinterDriver)(LPWSTR, LPWSTR, LPWSTR);
57 DWORD (WINAPI *fpAddPrintProcessor)(LPWSTR, LPWSTR, LPWSTR, LPWSTR);
58 DWORD (WINAPI *fpEnumPrintProcessors)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
59 DWORD (WINAPI *fpGetPrintProcessorDirectory)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
60 DWORD (WINAPI *fpDeletePrintProcessor)(LPWSTR, LPWSTR, LPWSTR);
61 DWORD (WINAPI *fpEnumPrintProcessorDatatypes)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
62 DWORD (WINAPI *fpStartDocPrinter)(HANDLE, DWORD, LPBYTE);
63 DWORD (WINAPI *fpStartPagePrinter)(HANDLE);
64 DWORD (WINAPI *fpWritePrinter)(HANDLE, LPVOID, DWORD, LPDWORD);
65 DWORD (WINAPI *fpEndPagePrinter)(HANDLE);
66 DWORD (WINAPI *fpAbortPrinter)(HANDLE);
67 DWORD (WINAPI *fpReadPrinter)(HANDLE, LPVOID, DWORD, LPDWORD);
68 DWORD (WINAPI *fpEndDocPrinter)(HANDLE);
69 DWORD (WINAPI *fpAddJob)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
70 DWORD (WINAPI *fpScheduleJob)(HANDLE, DWORD);
71 DWORD (WINAPI *fpGetPrinterData)(HANDLE, LPWSTR, LPDWORD, LPBYTE, DWORD, LPDWORD);
72 DWORD (WINAPI *fpSetPrinterData)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD);
73 DWORD (WINAPI *fpWaitForPrinterChange)(HANDLE, DWORD);
74 DWORD (WINAPI *fpClosePrinter)(HANDLE);
75 DWORD (WINAPI *fpAddForm)(HANDLE, DWORD, LPBYTE);
76 DWORD (WINAPI *fpDeleteForm)(HANDLE, LPWSTR);
77 DWORD (WINAPI *fpGetForm)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
78 DWORD (WINAPI *fpSetForm)(HANDLE, LPWSTR, DWORD, LPBYTE);
79 DWORD (WINAPI *fpEnumForms)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
80 DWORD (WINAPI *fpEnumMonitors)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
81 DWORD (WINAPI *fpEnumPorts)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
82 DWORD (WINAPI *fpAddPort)(LPWSTR, HWND, LPWSTR);
83 DWORD (WINAPI *fpConfigurePort)(LPWSTR, HWND, LPWSTR);
84 DWORD (WINAPI *fpDeletePort)(LPWSTR, HWND, LPWSTR);
85 HANDLE (WINAPI *fpCreatePrinterIC)(HANDLE, LPDEVMODEW);
86 DWORD (WINAPI *fpPlayGdiScriptOnPrinterIC)(HANDLE, LPBYTE, DWORD, LPBYTE, DWORD, DWORD);
87 DWORD (WINAPI *fpDeletePrinterIC)(HANDLE);
88 DWORD (WINAPI *fpAddPrinterConnection)(LPWSTR);
89 DWORD (WINAPI *fpDeletePrinterConnection)(LPWSTR);
90 DWORD (WINAPI *fpPrinterMessageBox)(HANDLE, DWORD, HWND, LPWSTR, LPWSTR, DWORD);
91 DWORD (WINAPI *fpAddMonitor)(LPWSTR, DWORD, LPBYTE);
92 DWORD (WINAPI *fpDeleteMonitor)(LPWSTR, LPWSTR, LPWSTR);
93 DWORD (WINAPI *fpResetPrinter)(HANDLE, LPPRINTER_DEFAULTSW);
94 DWORD (WINAPI *fpGetPrinterDriverEx)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, DWORD, DWORD, PDWORD, PDWORD);
95 HANDLE (WINAPI *fpFindFirstPrinterChangeNotification)(HANDLE, DWORD, DWORD, LPVOID);
96 DWORD (WINAPI *fpFindClosePrinterChangeNotification)(HANDLE);
97 DWORD (WINAPI *fpAddPortEx)(HANDLE, LPWSTR, DWORD, LPBYTE, LPWSTR);
98 DWORD (WINAPI *fpShutDown)(LPVOID);
99 DWORD (WINAPI *fpRefreshPrinterChangeNotification)(HANDLE, DWORD, PVOID, PVOID);
100 DWORD (WINAPI *fpOpenPrinterEx)(LPWSTR, LPHANDLE, LPPRINTER_DEFAULTSW, LPBYTE, DWORD);
101 HANDLE (WINAPI *fpAddPrinterEx)(LPWSTR, DWORD, LPBYTE, LPBYTE, DWORD);
102 DWORD (WINAPI *fpSetPort)(LPWSTR, LPWSTR, DWORD, LPBYTE);
103 DWORD (WINAPI *fpEnumPrinterData)(HANDLE, DWORD, LPWSTR, DWORD, LPDWORD, LPDWORD, LPBYTE, DWORD, LPDWORD);
104 DWORD (WINAPI *fpDeletePrinterData)(HANDLE, LPWSTR);
105 DWORD (WINAPI *fpClusterSplOpen)(LPCWSTR, LPCWSTR, PHANDLE, LPCWSTR, LPCWSTR);
106 DWORD (WINAPI *fpClusterSplClose)(HANDLE);
107 DWORD (WINAPI *fpClusterSplIsAlive)(HANDLE);
108 DWORD (WINAPI *fpSetPrinterDataEx)(HANDLE, LPCWSTR, LPCWSTR, DWORD, LPBYTE, DWORD);
109 DWORD (WINAPI *fpGetPrinterDataEx)(HANDLE, LPCWSTR, LPCWSTR, LPDWORD, LPBYTE, DWORD, LPDWORD);
110 DWORD (WINAPI *fpEnumPrinterDataEx)(HANDLE, LPCWSTR, LPBYTE, DWORD, LPDWORD, LPDWORD);
111 DWORD (WINAPI *fpEnumPrinterKey)(HANDLE, LPCWSTR, LPWSTR, DWORD, LPDWORD);
112 DWORD (WINAPI *fpDeletePrinterDataEx)(HANDLE, LPCWSTR, LPCWSTR);
113 DWORD (WINAPI *fpDeletePrinterKey)(HANDLE hPrinter, LPCWSTR pKeyName);
114 DWORD (WINAPI *fpSeekPrinter)(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD, BOOL);
115 DWORD (WINAPI *fpDeletePrinterDriverEx)(LPWSTR, LPWSTR, LPWSTR, DWORD, DWORD);
116 DWORD (WINAPI *fpAddPerMachineConnection)(LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);
117 DWORD (WINAPI *fpDeletePerMachineConnection)(LPCWSTR, LPCWSTR);
118 DWORD (WINAPI *fpEnumPerMachineConnections)(LPCWSTR, LPBYTE, DWORD, LPDWORD, LPDWORD);
119 DWORD (WINAPI *fpXcvData)(HANDLE, LPCWSTR, PBYTE, DWORD, PBYTE, DWORD, PDWORD, PDWORD);
120 DWORD (WINAPI *fpAddPrinterDriverEx)(LPWSTR, DWORD, LPBYTE, DWORD);
121 DWORD (WINAPI *fpSplReadPrinter)(HANDLE, LPBYTE *, DWORD);
122 DWORD (WINAPI *fpDriverUnloadComplete)(LPWSTR);
123 DWORD (WINAPI *fpGetSpoolFileInfo)(HANDLE, LPWSTR *, LPHANDLE, HANDLE, HANDLE);
124 DWORD (WINAPI *fpCommitSpoolData)(HANDLE, DWORD);
125 DWORD (WINAPI *fpCloseSpoolFileHandle)(HANDLE);
126 DWORD (WINAPI *fpFlushPrinter)(HANDLE, LPBYTE, DWORD, LPDWORD, DWORD);
127 DWORD (WINAPI *fpSendRecvBidiData)(HANDLE, LPCWSTR, LPBIDI_REQUEST_CONTAINER, LPBIDI_RESPONSE_CONTAINER *);
128 DWORD (WINAPI *fpAddDriverCatalog)(HANDLE, DWORD, VOID *, DWORD);
129 /* Private Data */
130 HMODULE dll;
131 LPWSTR dllname;
132 LPWSTR name;
133 LPWSTR regroot;
134 DWORD index;
135 } backend_t;
136
137 /* ################################ */
138
139 static backend_t *backend[MAX_BACKEND];
140 static DWORD used_backends = 0;
141
142 static CRITICAL_SECTION backend_cs;
143 static CRITICAL_SECTION_DEBUG backend_cs_debug =
144 {
145 0, 0, &backend_cs,
146 { &backend_cs_debug.ProcessLocksList, &backend_cs_debug.ProcessLocksList },
147 0, 0, { (DWORD_PTR)(__FILE__ ": backend_cs") }
148 };
149 static CRITICAL_SECTION backend_cs = { &backend_cs_debug, -1, 0, 0, 0, 0 };
150
151 /* ################################ */
152
153 static WCHAR localsplW[] = {'l','o','c','a','l','s','p','l','.','d','l','l',0};
154
155 /******************************************************************
156 * strdupW [internal]
157 *
158 * create a copy of a unicode-string
159 *
160 */
161
162 static LPWSTR strdupW(LPCWSTR p)
163 {
164 LPWSTR ret;
165 DWORD len;
166
167 if(!p) return NULL;
168 len = (lstrlenW(p) + 1) * sizeof(WCHAR);
169 ret = heap_alloc(len);
170 memcpy(ret, p, len);
171 return ret;
172 }
173
174 /******************************************************************
175 * backend_unload_all [internal]
176 *
177 * unload all backends
178 */
179 void backend_unload_all(void)
180 {
181 EnterCriticalSection(&backend_cs);
182 while (used_backends > 0) {
183 used_backends--;
184 FreeLibrary(backend[used_backends]->dll);
185 heap_free(backend[used_backends]->dllname);
186 heap_free(backend[used_backends]->name);
187 heap_free(backend[used_backends]->regroot);
188 heap_free(backend[used_backends]);
189 backend[used_backends] = NULL;
190 }
191 LeaveCriticalSection(&backend_cs);
192 }
193
194 /******************************************************************************
195 * backend_load [internal]
196 *
197 * load and init a backend
198 *
199 * PARAMS
200 * name [I] Printprovider to use for the backend. NULL for the local print provider
201 *
202 * RETURNS
203 * Success: PTR to the backend
204 * Failure: NULL
205 *
206 */
207 static backend_t * backend_load(LPWSTR dllname, LPWSTR name, LPWSTR regroot)
208 {
209
210 BOOL (WINAPI *pInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR);
211 DWORD id;
212 DWORD res;
213
214 TRACE("(%s, %s, %s)\n", debugstr_w(dllname), debugstr_w(name), debugstr_w(regroot));
215
216 EnterCriticalSection(&backend_cs);
217 id = used_backends;
218
219 backend[id] = heap_alloc_zero(sizeof(backend_t));
220 if (!backend[id]) {
221 LeaveCriticalSection(&backend_cs);
222 return NULL;
223 }
224
225 backend[id]->dllname = strdupW(dllname);
226 backend[id]->name = strdupW(name);
227 backend[id]->regroot = strdupW(regroot);
228
229 backend[id]->dll = LoadLibraryW(dllname);
230 if (backend[id]->dll) {
231 pInitializePrintProvidor = (void *) GetProcAddress(backend[id]->dll, "InitializePrintProvidor");
232 if (pInitializePrintProvidor) {
233
234 /* native localspl does not clear unused entries */
235 res = pInitializePrintProvidor((PRINTPROVIDOR *) backend[id], sizeof(PRINTPROVIDOR), regroot);
236 if (res) {
237 used_backends++;
238 backend[id]->index = used_backends;
239 LeaveCriticalSection(&backend_cs);
240 TRACE("--> backend #%d: %p (%s)\n", id, backend[id], debugstr_w(dllname));
241 return backend[id];
242 }
243 }
244 FreeLibrary(backend[id]->dll);
245 }
246 heap_free(backend[id]->dllname);
247 heap_free(backend[id]->name);
248 heap_free(backend[id]->regroot);
249 heap_free(backend[id]);
250 backend[id] = NULL;
251 LeaveCriticalSection(&backend_cs);
252 WARN("failed to init %s: %u\n", debugstr_w(dllname), GetLastError());
253 return NULL;
254 }
255
256 /******************************************************************************
257 * backend_load_all [internal]
258 *
259 * load and init all backends
260 *
261 * RETURNS
262 * Success: TRUE
263 * Failure: FALSE
264 *
265 */
266 BOOL backend_load_all(void)
267 {
268 static BOOL failed = FALSE;
269 backend_t * pb;
270
271 EnterCriticalSection(&backend_cs);
272
273 /* if we failed before, don't try again */
274 if (!failed && (used_backends == 0)) {
275 pb = backend_load(localsplW, NULL, NULL);
276
277 /* ToDo: parse the registry and load all other backends */
278
279 failed = (used_backends == 0);
280 }
281 LeaveCriticalSection(&backend_cs);
282 TRACE("-> %d\n", !failed);
283 return (!failed);
284 }
285
286 /******************************************************************************
287 * backend_first [internal]
288 *
289 * find the first usable backend
290 *
291 * RETURNS
292 * Success: PTR to the backend
293 * Failure: NULL
294 *
295 */
296 static backend_t * backend_first(LPWSTR name)
297 {
298
299 EnterCriticalSection(&backend_cs);
300 /* Load all backends, when not done yet */
301 if (used_backends || backend_load_all()) {
302
303 /* test for the local system first */
304 if (!name || !name[0]) {
305 LeaveCriticalSection(&backend_cs);
306 return backend[0];
307 }
308 }
309
310 FIXME("server %s not supported in %d backends\n", debugstr_w(name), used_backends);
311 LeaveCriticalSection(&backend_cs);
312 return NULL;
313 }
314
315 /******************************************************************
316 * AddMonitorW (spoolss.@)
317 *
318 * Install a Printmonitor
319 *
320 * PARAMS
321 * pName [I] Servername or NULL (local Computer)
322 * Level [I] Structure-Level (Must be 2)
323 * pMonitors [I] PTR to MONITOR_INFO_2
324 *
325 * RETURNS
326 * Success: TRUE
327 * Failure: FALSE
328 *
329 * NOTES
330 * All Files for the Monitor must already be copied to %winsysdir% ("%SystemRoot%\system32")
331 *
332 */
333 BOOL WINAPI AddMonitorW(LPWSTR pName, DWORD Level, LPBYTE pMonitors)
334 {
335 backend_t * pb;
336 DWORD res = ROUTER_UNKNOWN;
337
338 TRACE("(%s, %d, %p)\n", debugstr_w(pName), Level, pMonitors);
339
340 if (Level != 2) {
341 SetLastError(ERROR_INVALID_LEVEL);
342 return FALSE;
343 }
344
345 pb = backend_first(pName);
346 if (pb && pb->fpAddMonitor)
347 res = pb->fpAddMonitor(pName, Level, pMonitors);
348 else
349 {
350 SetLastError(ERROR_PROC_NOT_FOUND);
351 }
352
353 TRACE("got %u with %u\n", res, GetLastError());
354 return (res == ROUTER_SUCCESS);
355 }
356
357 /******************************************************************
358 * AddPrinterDriverExW (spoolss.@)
359 *
360 * Install a Printer Driver with the Option to upgrade / downgrade the Files
361 *
362 * PARAMS
363 * pName [I] Servername or NULL (local Computer)
364 * level [I] Level for the supplied DRIVER_INFO_*W struct
365 * pDriverInfo [I] PTR to DRIVER_INFO_*W struct with the Driver Parameter
366 * dwFileCopyFlags [I] How to Copy / Upgrade / Downgrade the needed Files
367 *
368 * RESULTS
369 * Success: TRUE
370 * Failure: FALSE
371 *
372 */
373 BOOL WINAPI AddPrinterDriverExW(LPWSTR pName, DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags)
374 {
375 backend_t * pb;
376 DWORD res = ROUTER_UNKNOWN;
377
378 TRACE("(%s, %d, %p, 0x%x)\n", debugstr_w(pName), level, pDriverInfo, dwFileCopyFlags);
379
380 if (!pDriverInfo) {
381 SetLastError(ERROR_INVALID_PARAMETER);
382 return FALSE;
383 }
384
385 pb = backend_first(pName);
386 if (pb && pb->fpAddPrinterDriverEx)
387 res = pb->fpAddPrinterDriverEx(pName, level, pDriverInfo, dwFileCopyFlags);
388 else
389 {
390 SetLastError(ERROR_PROC_NOT_FOUND);
391 }
392
393 TRACE("got %u with %u\n", res, GetLastError());
394 return (res == ROUTER_SUCCESS);
395 }
396
397 /******************************************************************
398 * DeleteMonitorW (spoolss.@)
399 *
400 * Delete a specific Printmonitor from a Printing-Environment
401 *
402 * PARAMS
403 * pName [I] Servername or NULL (local Computer)
404 * pEnvironment [I] Printing-Environment of the Monitor or NULL (Default)
405 * pMonitorName [I] Name of the Monitor, that should be deleted
406 *
407 * RETURNS
408 * Success: TRUE
409 * Failure: FALSE
410 *
411 */
412 BOOL WINAPI DeleteMonitorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pMonitorName)
413 {
414 backend_t * pb;
415 DWORD res = ROUTER_UNKNOWN;
416
417 TRACE("(%s, %s, %s)\n", debugstr_w(pName), debugstr_w(pEnvironment), debugstr_w(pMonitorName));
418
419 pb = backend_first(pName);
420 if (pb && pb->fpDeleteMonitor)
421 res = pb->fpDeleteMonitor(pName, pEnvironment, pMonitorName);
422 else
423 {
424 SetLastError(ERROR_PROC_NOT_FOUND);
425 }
426
427 TRACE("got %u with %u\n", res, GetLastError());
428 return (res == ROUTER_SUCCESS);
429 }
430
431 /******************************************************************
432 * EnumMonitorsW (spoolss.@)
433 *
434 * Enumerate available Port-Monitors
435 *
436 * PARAMS
437 * pName [I] Servername or NULL (local Computer)
438 * Level [I] Structure-Level
439 * pMonitors [O] PTR to Buffer that receives the Result
440 * cbBuf [I] Size of Buffer at pMonitors
441 * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pMonitors
442 * pcReturned [O] PTR to DWORD that receives the number of Monitors in pMonitors
443 *
444 * RETURNS
445 * Success: TRUE
446 * Failure: FALSE and in pcbNeeded the Bytes required for pMonitors, if cbBuf is too small
447 *
448 */
449 BOOL WINAPI EnumMonitorsW(LPWSTR pName, DWORD Level, LPBYTE pMonitors, DWORD cbBuf,
450 LPDWORD pcbNeeded, LPDWORD pcReturned)
451 {
452 backend_t * pb;
453 DWORD res = ROUTER_UNKNOWN;
454
455 TRACE("(%s, %d, %p, %d, %p, %p)\n", debugstr_w(pName), Level, pMonitors,
456 cbBuf, pcbNeeded, pcReturned);
457
458 if (pcbNeeded) *pcbNeeded = 0;
459 if (pcReturned) *pcReturned = 0;
460
461 pb = backend_first(pName);
462 if (pb && pb->fpEnumMonitors)
463 res = pb->fpEnumMonitors(pName, Level, pMonitors, cbBuf, pcbNeeded, pcReturned);
464 else
465 {
466 SetLastError(ERROR_PROC_NOT_FOUND);
467 }
468
469 TRACE("got %u with %u (%u byte for %u entries)\n\n", res, GetLastError(),
470 pcbNeeded ? *pcbNeeded : 0, pcReturned ? *pcReturned : 0);
471
472 return (res == ROUTER_SUCCESS);
473 }
474
475 /******************************************************************
476 * EnumPortsW (spoolss.@)
477 *
478 * Enumerate available Ports
479 *
480 * PARAMS
481 * pName [I] Servername or NULL (local Computer)
482 * Level [I] Structure-Level (1 or 2)
483 * pPorts [O] PTR to Buffer that receives the Result
484 * cbBuf [I] Size of Buffer at pPorts
485 * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPorts
486 * pcReturned [O] PTR to DWORD that receives the number of Ports in pPorts
487 *
488 * RETURNS
489 * Success: TRUE
490 * Failure: FALSE and in pcbNeeded the Bytes required for pPorts, if cbBuf is too small
491 *
492 */
493 BOOL WINAPI EnumPortsW(LPWSTR pName, DWORD Level, LPBYTE pPorts, DWORD cbBuf,
494 LPDWORD pcbNeeded, LPDWORD pcReturned)
495 {
496 backend_t * pb;
497 DWORD res = ROUTER_UNKNOWN;
498
499 TRACE("(%s, %d, %p, %d, %p, %p)\n", debugstr_w(pName), Level, pPorts, cbBuf,
500 pcbNeeded, pcReturned);
501
502 if (pcbNeeded) *pcbNeeded = 0;
503 if (pcReturned) *pcReturned = 0;
504
505 pb = backend_first(pName);
506 if (pb && pb->fpEnumPorts)
507 res = pb->fpEnumPorts(pName, Level, pPorts, cbBuf, pcbNeeded, pcReturned);
508 else
509 {
510 SetLastError(ERROR_PROC_NOT_FOUND);
511 }
512
513 TRACE("got %u with %u (%u byte for %u entries)\n", res, GetLastError(),
514 pcbNeeded ? *pcbNeeded : 0, pcReturned ? *pcReturned : 0);
515
516 return (res == ROUTER_SUCCESS);
517 }
518
519 /******************************************************************
520 * GetPrinterDriverDirectoryW (spoolss.@)
521 *
522 * Return the PATH for the Printer-Drivers
523 *
524 * PARAMS
525 * pName [I] Servername or NULL (local Computer)
526 * pEnvironment [I] Printing-Environment or NULL (Default)
527 * Level [I] Structure-Level (must be 1)
528 * pDriverDirectory [O] PTR to Buffer that receives the Result
529 * cbBuf [I] Size of Buffer at pDriverDirectory
530 * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used /
531 * required for pDriverDirectory
532 *
533 * RETURNS
534 * Success: TRUE and in pcbNeeded the Bytes used in pDriverDirectory
535 * Failure: FALSE and in pcbNeeded the Bytes required for pDriverDirectory,
536 * if cbBuf is too small
537 *
538 * Native Values returned in pDriverDirectory on Success:
539 *| NT(Windows NT x86): "%winsysdir%\\spool\\DRIVERS\\w32x86"
540 *| NT(Windows x64): "%winsysdir%\\spool\\DRIVERS\\x64"
541 *| NT(Windows 4.0): "%winsysdir%\\spool\\DRIVERS\\win40"
542 *| win9x(Windows 4.0): "%winsysdir%"
543 *
544 * "%winsysdir%" is the Value from GetSystemDirectoryW()
545 *
546 */
547 BOOL WINAPI GetPrinterDriverDirectoryW(LPWSTR pName, LPWSTR pEnvironment,
548 DWORD Level, LPBYTE pDriverDirectory, DWORD cbBuf, LPDWORD pcbNeeded)
549 {
550 backend_t * pb;
551 DWORD res = ROUTER_UNKNOWN;
552
553 TRACE("(%s, %s, %d, %p, %d, %p)\n", debugstr_w(pName),
554 debugstr_w(pEnvironment), Level, pDriverDirectory, cbBuf, pcbNeeded);
555
556 if (pcbNeeded) *pcbNeeded = 0;
557
558 pb = backend_first(pName);
559 if (pb && pb->fpGetPrinterDriverDirectory)
560 res = pb->fpGetPrinterDriverDirectory(pName, pEnvironment, Level,
561 pDriverDirectory, cbBuf, pcbNeeded);
562 else
563 {
564 SetLastError(ERROR_PROC_NOT_FOUND);
565 }
566
567 TRACE("got %u with %u (%u byte)\n",
568 res, GetLastError(), pcbNeeded ? *pcbNeeded : 0);
569
570 return (res == ROUTER_SUCCESS);
571
572 }
573
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.