1/*
2   Unix SMB/CIFS implementation.
3   RPC pipe client
4
5   Copyright (C) Gerald Carter                2001-2002,
6   Copyright (C) Tim Potter                   2000-2002,
7   Copyright (C) Andrew Tridgell              1994-2000,
8   Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
9   Copyright (C) Jean-Francois Micouleau      1999-2000.
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#include "includes.h"
27
28/** @defgroup spoolss SPOOLSS - NT printing routines
29 *  @ingroup rpc_client
30 *
31 * @{
32 **/
33
34/**********************************************************************
35 Initialize a new spoolss buff for use by a client rpc
36**********************************************************************/
37static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
38{
39	buffer->ptr = (size != 0);
40	buffer->size = size;
41	buffer->string_at_end = size;
42	prs_init(&buffer->prs, size, ctx, MARSHALL);
43	buffer->struct_start = prs_offset(&buffer->prs);
44}
45
46/*********************************************************************
47 Decode various spoolss rpc's and info levels
48 ********************************************************************/
49
50/**********************************************************************
51**********************************************************************/
52static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
53				uint32 returned, PRINTER_INFO_0 **info)
54{
55        uint32 i;
56        PRINTER_INFO_0  *inf;
57
58        inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
59	memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
60
61	prs_set_offset(&buffer->prs,0);
62
63        for (i=0; i<returned; i++) {
64                smb_io_printer_info_0("", buffer, &inf[i], 0);
65        }
66
67        *info=inf;
68}
69
70/**********************************************************************
71**********************************************************************/
72static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
73				uint32 returned, PRINTER_INFO_1 **info)
74{
75        uint32 i;
76        PRINTER_INFO_1  *inf;
77
78        inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
79	memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
80
81	prs_set_offset(&buffer->prs,0);
82
83        for (i=0; i<returned; i++) {
84                smb_io_printer_info_1("", buffer, &inf[i], 0);
85        }
86
87        *info=inf;
88}
89
90/**********************************************************************
91**********************************************************************/
92static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
93				uint32 returned, PRINTER_INFO_2 **info)
94{
95        uint32 i;
96        PRINTER_INFO_2  *inf;
97
98        inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
99	memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
100
101	prs_set_offset(&buffer->prs,0);
102
103        for (i=0; i<returned; i++) {
104		/* a little initialization as we go */
105		inf[i].secdesc = NULL;
106                smb_io_printer_info_2("", buffer, &inf[i], 0);
107        }
108
109        *info=inf;
110}
111
112/**********************************************************************
113**********************************************************************/
114static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
115				uint32 returned, PRINTER_INFO_3 **info)
116{
117        uint32 i;
118        PRINTER_INFO_3  *inf;
119
120        inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
121	memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
122
123	prs_set_offset(&buffer->prs,0);
124
125        for (i=0; i<returned; i++) {
126		inf[i].secdesc = NULL;
127                smb_io_printer_info_3("", buffer, &inf[i], 0);
128        }
129
130        *info=inf;
131}
132
133/**********************************************************************
134**********************************************************************/
135static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
136			uint32 returned, PORT_INFO_1 **info)
137{
138        uint32 i;
139        PORT_INFO_1 *inf;
140
141        inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
142	memset(inf, 0, returned*sizeof(PORT_INFO_1));
143
144        prs_set_offset(&buffer->prs, 0);
145
146        for (i=0; i<returned; i++) {
147                smb_io_port_info_1("", buffer, &(inf[i]), 0);
148        }
149
150        *info=inf;
151}
152
153/**********************************************************************
154**********************************************************************/
155static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
156			uint32 returned, PORT_INFO_2 **info)
157{
158        uint32 i;
159        PORT_INFO_2 *inf;
160
161        inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
162	memset(inf, 0, returned*sizeof(PORT_INFO_2));
163
164        prs_set_offset(&buffer->prs, 0);
165
166        for (i=0; i<returned; i++) {
167                smb_io_port_info_2("", buffer, &(inf[i]), 0);
168        }
169
170        *info=inf;
171}
172
173/**********************************************************************
174**********************************************************************/
175static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
176			uint32 returned, DRIVER_INFO_1 **info)
177{
178        uint32 i;
179        DRIVER_INFO_1 *inf;
180
181        inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
182	memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
183
184	prs_set_offset(&buffer->prs,0);
185
186        for (i=0; i<returned; i++) {
187                smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
188        }
189
190        *info=inf;
191}
192
193/**********************************************************************
194**********************************************************************/
195static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
196			uint32 returned, DRIVER_INFO_2 **info)
197{
198        uint32 i;
199        DRIVER_INFO_2 *inf;
200
201        inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
202	memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
203
204	prs_set_offset(&buffer->prs,0);
205
206        for (i=0; i<returned; i++) {
207                smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
208        }
209
210        *info=inf;
211}
212
213/**********************************************************************
214**********************************************************************/
215static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
216			uint32 returned, DRIVER_INFO_3 **info)
217{
218        uint32 i;
219        DRIVER_INFO_3 *inf;
220
221        inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
222	memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
223
224	prs_set_offset(&buffer->prs,0);
225
226        for (i=0; i<returned; i++) {
227                smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
228        }
229
230        *info=inf;
231}
232
233/**********************************************************************
234**********************************************************************/
235static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
236			uint32 returned, DRIVER_DIRECTORY_1 **info
237)
238{
239	DRIVER_DIRECTORY_1 *inf;
240
241        inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
242	memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
243
244        prs_set_offset(&buffer->prs, 0);
245
246        smb_io_driverdir_1("", buffer, inf, 0);
247
248	*info=inf;
249}
250
251/** Return a handle to the specified printer or print server.
252 *
253 * @param cli              Pointer to client state structure which is open
254 * on the SPOOLSS pipe.
255 *
256 * @param mem_ctx          Pointer to an initialised talloc context.
257 *
258 * @param printername      The name of the printer or print server to be
259 * opened in UNC format.
260 *
261 * @param datatype         Specifies the default data type for the printer.
262 *
263 * @param access_required  The access rights requested on the printer or
264 * print server.
265 *
266 * @param station          The UNC name of the requesting workstation.
267 *
268 * @param username         The name of the user requesting the open.
269 *
270 * @param pol              Returned policy handle.
271 */
272
273/*********************************************************************************
274 Win32 API - OpenPrinter()
275 ********************************************************************************/
276
277WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
278				const char *printername, const char *datatype, uint32 access_required,
279				const char *station, const char *username, POLICY_HND *pol)
280{
281	prs_struct qbuf, rbuf;
282	SPOOL_Q_OPEN_PRINTER_EX q;
283	SPOOL_R_OPEN_PRINTER_EX r;
284	WERROR result = W_ERROR(ERRgeneral);
285
286	ZERO_STRUCT(q);
287	ZERO_STRUCT(r);
288
289	/* Initialise parse structures */
290
291	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
292	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
293
294	/* Initialise input parameters */
295
296        make_spoolss_q_open_printer_ex(&q, printername, datatype,
297                                       access_required, station, username);
298
299	/* Marshall data and send request */
300
301	if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
302	    !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
303		goto done;
304
305	/* Unmarshall response */
306
307	if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0))
308		goto done;
309
310	/* Return output parameters */
311
312	result = r.status;
313
314	if (W_ERROR_IS_OK(result))
315		*pol = r.handle;
316
317 done:
318	prs_mem_free(&qbuf);
319	prs_mem_free(&rbuf);
320
321	return result;
322}
323
324/** Close a printer handle
325 *
326 * @param cli              Pointer to client state structure which is open
327 * on the SPOOLSS pipe.
328 *
329 * @param mem_ctx          Pointer to an initialised talloc context.
330 *
331 * @param pol              Policy handle of printer or print server to close.
332 */
333/*********************************************************************************
334 Win32 API - ClosePrinter()
335 ********************************************************************************/
336
337WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
338				 POLICY_HND *pol)
339{
340	prs_struct qbuf, rbuf;
341	SPOOL_Q_CLOSEPRINTER q;
342	SPOOL_R_CLOSEPRINTER r;
343	WERROR result = W_ERROR(ERRgeneral);
344
345	ZERO_STRUCT(q);
346	ZERO_STRUCT(r);
347
348	/* Initialise parse structures */
349
350	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
351	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
352
353	/* Initialise input parameters */
354
355        make_spoolss_q_closeprinter(&q, pol);
356
357	/* Marshall data and send request */
358
359	if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
360	    !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
361		goto done;
362
363	/* Unmarshall response */
364
365	if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0))
366		goto done;
367
368	/* Return output parameters */
369
370	result = r.status;
371
372	if (W_ERROR_IS_OK(result))
373		*pol = r.handle;
374
375 done:
376	prs_mem_free(&qbuf);
377	prs_mem_free(&rbuf);
378
379	return result;
380}
381
382/** Enumerate printers on a print server.
383 *
384 * @param cli              Pointer to client state structure which is open
385 *                         on the SPOOLSS pipe.
386 * @param mem_ctx          Pointer to an initialised talloc context.
387 *
388 * @param offered          Buffer size offered in the request.
389 * @param needed           Number of bytes needed to complete the request.
390 *                         may be NULL.
391 *
392 * @param flags            Selected from PRINTER_ENUM_* flags.
393 * @param level            Request information level.
394 *
395 * @param num_printers     Pointer to number of printers returned.  May be
396 *                         NULL.
397 * @param ctr              Return structure for printer information.  May
398 *                         be NULL.
399 */
400/*********************************************************************************
401 Win32 API - EnumPrinters()
402 ********************************************************************************/
403
404WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
405				 uint32 offered, uint32 *needed,
406				 char *name, uint32 flags, uint32 level,
407				 uint32 *num_printers, PRINTER_INFO_CTR *ctr)
408{
409	prs_struct qbuf, rbuf;
410	SPOOL_Q_ENUMPRINTERS q;
411        SPOOL_R_ENUMPRINTERS r;
412	NEW_BUFFER buffer;
413	WERROR result = W_ERROR(ERRgeneral);
414
415	ZERO_STRUCT(q);
416	ZERO_STRUCT(r);
417
418	/* Initialise input parameters */
419
420	init_buffer(&buffer, offered, mem_ctx);
421
422	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
423	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
424
425	make_spoolss_q_enumprinters(&q, flags, name, level, &buffer,
426				    offered);
427
428	/* Marshall data and send request */
429
430	if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
431	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
432		goto done;
433
434	/* Unmarshall response */
435
436	if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
437		if (needed)
438			*needed = r.needed;
439	}
440
441	result = r.status;
442
443	/* Return output parameters */
444
445	if (!W_ERROR_IS_OK(r.status))
446		goto done;
447
448	if (num_printers)
449		*num_printers = r.returned;
450
451	if (!ctr)
452		goto done;
453
454	switch (level) {
455	case 0:
456		decode_printer_info_0(mem_ctx, r.buffer, r.returned,
457				      &ctr->printers_0);
458		break;
459	case 1:
460		decode_printer_info_1(mem_ctx, r.buffer, r.returned,
461				      &ctr->printers_1);
462		break;
463	case 2:
464		decode_printer_info_2(mem_ctx, r.buffer, r.returned,
465				      &ctr->printers_2);
466		break;
467	case 3:
468		decode_printer_info_3(mem_ctx, r.buffer, r.returned,
469				      &ctr->printers_3);
470		break;
471	}
472
473 done:
474	prs_mem_free(&qbuf);
475	prs_mem_free(&rbuf);
476
477	return result;
478}
479
480/*********************************************************************************
481 Win32 API - EnumPorts()
482 ********************************************************************************/
483/** Enumerate printer ports on a print server.
484 *
485 * @param cli              Pointer to client state structure which is open
486 *                         on the SPOOLSS pipe.
487 * @param mem_ctx          Pointer to an initialised talloc context.
488 *
489 * @param offered          Buffer size offered in the request.
490 * @param needed           Number of bytes needed to complete the request.
491 *                         May be NULL.
492 *
493 * @param level            Requested information level.
494 *
495 * @param num_ports        Pointer to number of ports returned.  May be NULL.
496 * @param ctr              Pointer to structure holding port information.
497 *                         May be NULL.
498 */
499
500WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
501			      uint32 offered, uint32 *needed,
502			      uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
503{
504	prs_struct qbuf, rbuf;
505	SPOOL_Q_ENUMPORTS q;
506        SPOOL_R_ENUMPORTS r;
507	NEW_BUFFER buffer;
508	WERROR result = W_ERROR(ERRgeneral);
509	fstring server;
510
511	ZERO_STRUCT(q);
512	ZERO_STRUCT(r);
513
514        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
515        strupper_m(server);
516
517	/* Initialise input parameters */
518
519	init_buffer(&buffer, offered, mem_ctx);
520
521	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
522	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
523
524	make_spoolss_q_enumports(&q, server, level, &buffer, offered);
525
526	/* Marshall data and send request */
527
528	if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
529	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
530		goto done;
531
532	/* Unmarshall response */
533
534	if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
535		if (needed)
536			*needed = r.needed;
537	}
538
539	result = r.status;
540
541	/* Return output parameters */
542
543	if (!W_ERROR_IS_OK(result))
544		goto done;
545
546	if (num_ports)
547		*num_ports = r.returned;
548
549	if (!ctr)
550		goto done;
551
552	switch (level) {
553	case 1:
554		decode_port_info_1(mem_ctx, r.buffer, r.returned,
555				   &ctr->port.info_1);
556		break;
557	case 2:
558		decode_port_info_2(mem_ctx, r.buffer, r.returned,
559				   &ctr->port.info_2);
560		break;
561	}
562
563 done:
564	prs_mem_free(&qbuf);
565	prs_mem_free(&rbuf);
566
567	return result;
568}
569
570/*********************************************************************************
571 Win32 API - GetPrinter()
572 ********************************************************************************/
573
574WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
575			      uint32 offered, uint32 *needed,
576			      POLICY_HND *pol, uint32 level,
577			      PRINTER_INFO_CTR *ctr)
578{
579	prs_struct qbuf, rbuf;
580	SPOOL_Q_GETPRINTER q;
581	SPOOL_R_GETPRINTER r;
582	NEW_BUFFER buffer;
583	WERROR result = W_ERROR(ERRgeneral);
584
585	ZERO_STRUCT(q);
586	ZERO_STRUCT(r);
587
588	/* Initialise input parameters */
589
590	init_buffer(&buffer, offered, mem_ctx);
591
592	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
593	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
594
595	make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered);
596
597	/* Marshall data and send request */
598
599	if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
600	    !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
601		goto done;
602
603	/* Unmarshall response */
604
605	if (!spoolss_io_r_getprinter("", &r, &rbuf, 0))
606		goto done;
607
608	if (needed)
609		*needed = r.needed;
610
611	/* Return output parameters */
612
613	result = r.status;
614
615	if (W_ERROR_IS_OK(result)) {
616		switch (level) {
617		case 0:
618			decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
619			break;
620		case 1:
621			decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
622			break;
623		case 2:
624			decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
625			break;
626		case 3:
627			decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
628			break;
629		}
630	}
631
632 done:
633	prs_mem_free(&qbuf);
634	prs_mem_free(&rbuf);
635
636	return result;
637}
638
639/*********************************************************************************
640 Win32 API - SetPrinter()
641 ********************************************************************************/
642/** Set printer info
643 *
644 * @param cli              Pointer to client state structure which is open
645 *                         on the SPOOLSS pipe.
646 * @param mem_ctx          Pointer to an initialised talloc context.
647 *
648 * @param pol              Policy handle on printer to set info.
649 * @param level            Information level to set.
650 * @param ctr              Pointer to structure holding printer information.
651 * @param command          Specifies the action performed.  See
652 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp
653 * for details.
654 *
655 */
656
657WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
658			      POLICY_HND *pol, uint32 level,
659			      PRINTER_INFO_CTR *ctr, uint32 command)
660{
661	prs_struct qbuf, rbuf;
662	SPOOL_Q_SETPRINTER q;
663	SPOOL_R_SETPRINTER r;
664	WERROR result = W_ERROR(ERRgeneral);
665
666	ZERO_STRUCT(q);
667	ZERO_STRUCT(r);
668
669	/* Initialise input parameters */
670
671	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
672	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
673
674	if (!make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command))
675		goto done;
676
677	/* Marshall data and send request */
678
679	if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
680	    !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
681		goto done;
682
683	/* Unmarshall response */
684
685	if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
686		goto done;
687
688	result = r.status;
689
690done:
691	prs_mem_free(&qbuf);
692	prs_mem_free(&rbuf);
693
694	return result;
695}
696
697/*********************************************************************************
698 Win32 API - GetPrinterDriver()
699 ********************************************************************************/
700/** Get installed printer drivers for a given printer
701 *
702 * @param cli              Pointer to client state structure which is open
703 * on the SPOOLSS pipe.
704 *
705 * @param mem_ctx          Pointer to an initialised talloc context.
706 *
707 * @param offered          Buffer size offered in the request.
708 * @param needed           Number of bytes needed to complete the request.
709 *                         may be NULL.
710 *
711 * @param pol              Pointer to an open policy handle for the printer
712 *                         opened with cli_spoolss_open_printer_ex().
713 * @param level            Requested information level.
714 * @param env              The print environment or archictecture.  This is
715 *                         "Windows NT x86" for NT4.
716 * @param ctr              Returned printer driver information.
717 */
718
719WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
720				    TALLOC_CTX *mem_ctx,
721				    uint32 offered, uint32 *needed,
722				    POLICY_HND *pol, uint32 level,
723				    const char *env, int version, PRINTER_DRIVER_CTR *ctr)
724{
725	prs_struct qbuf, rbuf;
726	SPOOL_Q_GETPRINTERDRIVER2 q;
727        SPOOL_R_GETPRINTERDRIVER2 r;
728	NEW_BUFFER buffer;
729	WERROR result = W_ERROR(ERRgeneral);
730	fstring server;
731
732	ZERO_STRUCT(q);
733	ZERO_STRUCT(r);
734
735	fstrcpy(server, cli->desthost);
736	strupper_m(server);
737
738	/* Initialise input parameters */
739
740	init_buffer(&buffer, offered, mem_ctx);
741
742	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
743	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
744
745	make_spoolss_q_getprinterdriver2(&q, pol, env, level, version, 2,
746					 &buffer, offered);
747
748	/* Marshall data and send request */
749
750	if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
751	    !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
752		goto done;
753
754	/* Unmarshall response */
755
756	if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) {
757		if (needed)
758			*needed = r.needed;
759	}
760
761	result = r.status;
762
763	/* Return output parameters */
764
765	if (!W_ERROR_IS_OK(result))
766		goto done;
767
768	if (!ctr)
769		goto done;
770
771	switch (level) {
772	case 1:
773		decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
774		break;
775	case 2:
776		decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
777		break;
778	case 3:
779		decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
780		break;
781	default:
782		DEBUG(10, ("cli_spoolss_getprinterdriver: unknown info level %d", level));
783		return WERR_UNKNOWN_LEVEL;
784	}
785
786 done:
787	prs_mem_free(&qbuf);
788	prs_mem_free(&rbuf);
789
790	return result;
791}
792
793/*********************************************************************************
794 Win32 API - EnumPrinterDrivers()
795 ********************************************************************************/
796/**********************************************************************
797 * Get installed printer drivers for a given printer
798 */
799WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
800				       TALLOC_CTX *mem_ctx,
801				       uint32 offered, uint32 *needed,
802				       uint32 level, const char *env,
803				       uint32 *num_drivers,
804				       PRINTER_DRIVER_CTR *ctr)
805{
806	prs_struct qbuf, rbuf;
807	SPOOL_Q_ENUMPRINTERDRIVERS q;
808        SPOOL_R_ENUMPRINTERDRIVERS r;
809	NEW_BUFFER buffer;
810	WERROR result = W_ERROR(ERRgeneral);
811	fstring server;
812
813	ZERO_STRUCT(q);
814	ZERO_STRUCT(r);
815
816        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
817        strupper_m(server);
818
819	/* Initialise input parameters */
820
821	init_buffer(&buffer, offered, mem_ctx);
822
823	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
824	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
825
826	/* Write the request */
827
828	make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer,
829					  offered);
830
831	/* Marshall data and send request */
832
833	if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
834	    !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
835		goto done;
836
837	/* Unmarshall response */
838
839	if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
840		goto done;
841
842	if (needed)
843		*needed = r.needed;
844
845	if (num_drivers)
846		*num_drivers = r.returned;
847
848	result = r.status;
849
850	/* Return output parameters */
851
852	if (W_ERROR_IS_OK(result) && (r.returned != 0)) {
853		*num_drivers = r.returned;
854
855		switch (level) {
856		case 1:
857			decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
858			break;
859		case 2:
860			decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
861			break;
862		case 3:
863			decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
864			break;
865		default:
866			DEBUG(10, ("cli_spoolss_enumprinterdrivers: unknown info level %d\n",
867				   level));
868			return WERR_UNKNOWN_LEVEL;
869		}
870	}
871
872 done:
873	prs_mem_free(&qbuf);
874	prs_mem_free(&rbuf);
875
876	return result;
877}
878
879
880/*********************************************************************************
881 Win32 API - GetPrinterDriverDirectory()
882 ********************************************************************************/
883/**********************************************************************
884 * Get installed printer drivers for a given printer
885 */
886WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
887					TALLOC_CTX *mem_ctx,
888					uint32 offered, uint32 *needed,
889					uint32 level, char *env,
890					DRIVER_DIRECTORY_CTR *ctr)
891{
892	prs_struct 			qbuf, rbuf;
893	SPOOL_Q_GETPRINTERDRIVERDIR 	q;
894        SPOOL_R_GETPRINTERDRIVERDIR 	r;
895	NEW_BUFFER 			buffer;
896	WERROR result = W_ERROR(ERRgeneral);
897	fstring 			server;
898
899	ZERO_STRUCT(q);
900	ZERO_STRUCT(r);
901
902        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
903        strupper_m(server);
904
905	/* Initialise input parameters */
906
907	init_buffer(&buffer, offered, mem_ctx);
908
909	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
910	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
911
912	/* Write the request */
913
914	make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer,
915					   offered);
916
917	/* Marshall data and send request */
918
919	if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
920	    !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
921			       &qbuf, &rbuf))
922		goto done;
923
924	/* Unmarshall response */
925
926	if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) {
927		if (needed)
928			*needed = r.needed;
929	}
930
931	/* Return output parameters */
932
933	result = r.status;
934
935	if (W_ERROR_IS_OK(result)) {
936		switch (level) {
937		case 1:
938			decode_printerdriverdir_1(mem_ctx, r.buffer, 1,
939						  &ctr->info1);
940			break;
941		}
942	}
943
944	done:
945		prs_mem_free(&qbuf);
946		prs_mem_free(&rbuf);
947
948	return result;
949}
950
951/*********************************************************************************
952 Win32 API - AddPrinterDriver()
953 ********************************************************************************/
954/**********************************************************************
955 * Install a printer driver
956 */
957WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
958				     TALLOC_CTX *mem_ctx, uint32 level,
959				     PRINTER_DRIVER_CTR *ctr)
960{
961	prs_struct 			qbuf, rbuf;
962	SPOOL_Q_ADDPRINTERDRIVER 	q;
963        SPOOL_R_ADDPRINTERDRIVER 	r;
964	WERROR result = W_ERROR(ERRgeneral);
965	fstring 			server;
966
967	ZERO_STRUCT(q);
968	ZERO_STRUCT(r);
969
970        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
971        strupper_m(server);
972
973	/* Initialise input parameters */
974
975	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
976	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
977
978	/* Write the request */
979
980	make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr);
981
982	/* Marshall data and send request */
983
984	if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
985	    !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
986		goto done;
987
988	/* Unmarshall response */
989
990	if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
991		goto done;
992
993	/* Return output parameters */
994
995	result = r.status;
996
997done:
998	prs_mem_free(&qbuf);
999	prs_mem_free(&rbuf);
1000
1001	return result;
1002}
1003
1004/*********************************************************************************
1005 Win32 API - AddPrinter()
1006 ********************************************************************************/
1007/**********************************************************************
1008 * Install a printer
1009 */
1010WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
1011				 uint32 level, PRINTER_INFO_CTR*ctr)
1012{
1013	prs_struct 			qbuf, rbuf;
1014	SPOOL_Q_ADDPRINTEREX 		q;
1015        SPOOL_R_ADDPRINTEREX 		r;
1016	WERROR result = W_ERROR(ERRgeneral);
1017	fstring 			server,
1018					client,
1019					user;
1020
1021	ZERO_STRUCT(q);
1022	ZERO_STRUCT(r);
1023
1024        slprintf(client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1025        strupper_m(client);
1026        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1027        strupper_m(server);
1028	fstrcpy  (user, cli->user_name);
1029
1030	/* Initialise input parameters */
1031
1032	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1033	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1034
1035	/* Write the request */
1036
1037	make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user,
1038				     level, ctr);
1039
1040	/* Marshall data and send request */
1041
1042	if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
1043	    !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
1044		goto done;
1045
1046	/* Unmarshall response */
1047
1048	if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
1049		goto done;
1050
1051	/* Return output parameters */
1052
1053	result = r.status;
1054
1055 done:
1056	prs_mem_free(&qbuf);
1057	prs_mem_free(&rbuf);
1058
1059	return result;
1060}
1061
1062/*********************************************************************************
1063 Win32 API - DeltePrinterDriver()
1064 ********************************************************************************/
1065/**********************************************************************
1066 * Delete a Printer Driver from the server (does not remove
1067 * the driver files
1068 */
1069WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
1070					TALLOC_CTX *mem_ctx, const char *arch,
1071					const char *driver)
1072{
1073	prs_struct 			qbuf, rbuf;
1074	SPOOL_Q_DELETEPRINTERDRIVER	q;
1075        SPOOL_R_DELETEPRINTERDRIVER	r;
1076	WERROR result = W_ERROR(ERRgeneral);
1077	fstring				server;
1078
1079	ZERO_STRUCT(q);
1080	ZERO_STRUCT(r);
1081
1082
1083	/* Initialise input parameters */
1084	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1085	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1086
1087        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1088        strupper_m(server);
1089
1090	/* Write the request */
1091
1092	make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver);
1093
1094	/* Marshall data and send request */
1095
1096	if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
1097	    !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
1098		goto done;
1099
1100	/* Unmarshall response */
1101
1102	if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0))
1103		goto done;
1104
1105	/* Return output parameters */
1106
1107	result = r.status;
1108
1109 done:
1110	prs_mem_free(&qbuf);
1111	prs_mem_free(&rbuf);
1112
1113	return result;
1114}
1115
1116/*********************************************************************************
1117 Win32 API - GetPrinterProcessorDirectory()
1118 ********************************************************************************/
1119
1120WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
1121					      TALLOC_CTX *mem_ctx,
1122					      uint32 offered, uint32 *needed,
1123					      char *name, char *environment,
1124					      fstring procdir)
1125{
1126	prs_struct qbuf, rbuf;
1127	SPOOL_Q_GETPRINTPROCESSORDIRECTORY q;
1128	SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
1129	int level = 1;
1130	WERROR result = W_ERROR(ERRgeneral);
1131	NEW_BUFFER buffer;
1132
1133	ZERO_STRUCT(q);
1134	ZERO_STRUCT(r);
1135
1136	/* Initialise parse structures */
1137
1138	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1139	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1140
1141	/* Initialise input parameters */
1142
1143	init_buffer(&buffer, offered, mem_ctx);
1144
1145	make_spoolss_q_getprintprocessordirectory(
1146		&q, name, environment, level, &buffer, offered);
1147
1148	/* Marshall data and send request */
1149
1150	if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
1151	    !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1152			      &qbuf, &rbuf))
1153		goto done;
1154
1155	/* Unmarshall response */
1156
1157	if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0))
1158		goto done;
1159
1160	/* Return output parameters */
1161
1162	result = r.status;
1163
1164	if (needed)
1165		*needed = r.needed;
1166
1167	if (W_ERROR_IS_OK(result))
1168		fstrcpy(procdir, "Not implemented!");
1169
1170 done:
1171	prs_mem_free(&qbuf);
1172	prs_mem_free(&rbuf);
1173
1174	return result;
1175}
1176
1177/** Add a form to a printer.
1178 *
1179 * @param cli              Pointer to client state structure which is open
1180 *                         on the SPOOLSS pipe.
1181 * @param mem_ctx          Pointer to an initialised talloc context.
1182 *
1183 * @param handle           Policy handle opened with cli_spoolss_open_printer_ex
1184 *                         or cli_spoolss_addprinterex.
1185 * @param level            Form info level to add - should always be 1.
1186 * @param form             A pointer to the form to be added.
1187 *
1188 */
1189
1190WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1191			   POLICY_HND *handle, uint32 level, FORM *form)
1192{
1193	prs_struct qbuf, rbuf;
1194	SPOOL_Q_ADDFORM q;
1195	SPOOL_R_ADDFORM r;
1196	WERROR result = W_ERROR(ERRgeneral);
1197
1198	ZERO_STRUCT(q);
1199	ZERO_STRUCT(r);
1200
1201	/* Initialise parse structures */
1202
1203	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1204	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1205
1206	/* Initialise input parameters */
1207
1208        make_spoolss_q_addform(&q, handle, level, form);
1209
1210	/* Marshall data and send request */
1211
1212	if (!spoolss_io_q_addform("", &q, &qbuf, 0) ||
1213	    !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf))
1214		goto done;
1215
1216	/* Unmarshall response */
1217
1218	if (!spoolss_io_r_addform("", &r, &rbuf, 0))
1219		goto done;
1220
1221	/* Return output parameters */
1222
1223	result = r.status;
1224
1225 done:
1226	prs_mem_free(&qbuf);
1227	prs_mem_free(&rbuf);
1228
1229	return result;
1230}
1231
1232/** Set a form on a printer.
1233 *
1234 * @param cli              Pointer to client state structure which is open
1235 *                         on the SPOOLSS pipe.
1236 * @param mem_ctx          Pointer to an initialised talloc context.
1237 *
1238 * @param handle           Policy handle opened with cli_spoolss_open_printer_ex
1239 *                         or cli_spoolss_addprinterex.
1240 * @param level            Form info level to set - should always be 1.
1241 * @param form             A pointer to the form to be set.
1242 *
1243 */
1244
1245WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1246			   POLICY_HND *handle, uint32 level,
1247			   const char *form_name, FORM *form)
1248{
1249	prs_struct qbuf, rbuf;
1250	SPOOL_Q_SETFORM q;
1251	SPOOL_R_SETFORM r;
1252	WERROR result = W_ERROR(ERRgeneral);
1253
1254	ZERO_STRUCT(q);
1255	ZERO_STRUCT(r);
1256
1257	/* Initialise parse structures */
1258
1259	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1260	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1261
1262	/* Initialise input parameters */
1263
1264        make_spoolss_q_setform(&q, handle, level, form_name, form);
1265
1266	/* Marshall data and send request */
1267
1268	if (!spoolss_io_q_setform("", &q, &qbuf, 0) ||
1269	    !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf))
1270		goto done;
1271
1272	/* Unmarshall response */
1273
1274	if (!spoolss_io_r_setform("", &r, &rbuf, 0))
1275		goto done;
1276
1277	/* Return output parameters */
1278
1279	result = r.status;
1280
1281	if (!W_ERROR_IS_OK(result))
1282		goto done;
1283
1284
1285
1286 done:
1287	prs_mem_free(&qbuf);
1288	prs_mem_free(&rbuf);
1289
1290	return result;
1291}
1292
1293/** Get a form on a printer.
1294 *
1295 * @param cli              Pointer to client state structure which is open
1296 *                         on the SPOOLSS pipe.
1297 * @param mem_ctx          Pointer to an initialised talloc context.
1298 *
1299 * @param handle           Policy handle opened with cli_spoolss_open_printer_ex
1300 *                         or cli_spoolss_addprinterex.
1301 * @param formname         Name of the form to get
1302 * @param level            Form info level to get - should always be 1.
1303 *
1304 */
1305
1306WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1307			   uint32 offered, uint32 *needed,
1308			   POLICY_HND *handle, const char *formname,
1309			   uint32 level, FORM_1 *form)
1310{
1311	prs_struct qbuf, rbuf;
1312	SPOOL_Q_GETFORM q;
1313	SPOOL_R_GETFORM r;
1314	WERROR result = W_ERROR(ERRgeneral);
1315	NEW_BUFFER buffer;
1316
1317	ZERO_STRUCT(q);
1318	ZERO_STRUCT(r);
1319
1320	/* Initialise parse structures */
1321
1322	init_buffer(&buffer, offered, mem_ctx);
1323
1324	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1325	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1326
1327	/* Initialise input parameters */
1328
1329        make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered);
1330
1331	/* Marshall data and send request */
1332
1333	if (!spoolss_io_q_getform("", &q, &qbuf, 0) ||
1334	    !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf))
1335		goto done;
1336
1337	/* Unmarshall response */
1338
1339	if (!spoolss_io_r_getform("", &r, &rbuf, 0))
1340		goto done;
1341
1342	/* Return output parameters */
1343
1344	result = r.status;
1345
1346	if (needed)
1347		*needed = r.needed;
1348
1349	if (W_ERROR_IS_OK(result)) {
1350		switch(level) {
1351		case 1:
1352			smb_io_form_1("", r.buffer, form, 0);
1353			break;
1354		default:
1355			DEBUG(10, ("cli_spoolss_getform: unknown info level %d", level));
1356			return WERR_UNKNOWN_LEVEL;
1357		}
1358	}
1359
1360 done:
1361	prs_mem_free(&qbuf);
1362	prs_mem_free(&rbuf);
1363
1364	return result;
1365}
1366
1367/** Delete a form on a printer.
1368 *
1369 * @param cli              Pointer to client state structure which is open
1370 *                         on the SPOOLSS pipe.
1371 * @param mem_ctx          Pointer to an initialised talloc context.
1372 *
1373 * @param handle           Policy handle opened with cli_spoolss_open_printer_ex
1374 *                         or cli_spoolss_addprinterex.
1375 * @param form             The name of the form to delete.
1376 *
1377 */
1378
1379WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1380			      POLICY_HND *handle, const char *form_name)
1381{
1382	prs_struct qbuf, rbuf;
1383	SPOOL_Q_DELETEFORM q;
1384	SPOOL_R_DELETEFORM r;
1385	WERROR result = W_ERROR(ERRgeneral);
1386
1387	ZERO_STRUCT(q);
1388	ZERO_STRUCT(r);
1389
1390	/* Initialise parse structures */
1391
1392	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1393	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1394
1395	/* Initialise input parameters */
1396
1397        make_spoolss_q_deleteform(&q, handle, form_name);
1398
1399	/* Marshall data and send request */
1400
1401	if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) ||
1402	    !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
1403		goto done;
1404
1405	/* Unmarshall response */
1406
1407	if (!spoolss_io_r_deleteform("", &r, &rbuf, 0))
1408		goto done;
1409
1410	/* Return output parameters */
1411
1412	result = r.status;
1413
1414 done:
1415	prs_mem_free(&qbuf);
1416	prs_mem_free(&rbuf);
1417
1418	return result;
1419}
1420
1421static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
1422			   uint32 num_forms, FORM_1 **forms)
1423{
1424	int i;
1425
1426	*forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
1427	prs_set_offset(&buffer->prs,0);
1428
1429	for (i = 0; i < num_forms; i++)
1430		smb_io_form_1("", buffer, &((*forms)[i]), 0);
1431}
1432
1433/** Enumerate forms
1434 *
1435 * @param cli              Pointer to client state structure which is open
1436 *                         on the SPOOLSS pipe.
1437 * @param mem_ctx          Pointer to an initialised talloc context.
1438 *
1439 * @param offered          Buffer size offered in the request.
1440 * @param needed           Number of bytes needed to complete the request.
1441 *                         may be NULL.
1442 *                         or cli_spoolss_addprinterex.
1443 * @param level            Form info level to get - should always be 1.
1444 * @param handle           Open policy handle
1445 *
1446 */
1447
1448WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1449			     uint32 offered, uint32 *needed,
1450			     POLICY_HND *handle, int level, uint32 *num_forms,
1451			     FORM_1 **forms)
1452{
1453	prs_struct qbuf, rbuf;
1454	SPOOL_Q_ENUMFORMS q;
1455	SPOOL_R_ENUMFORMS r;
1456	WERROR result = W_ERROR(ERRgeneral);
1457	NEW_BUFFER buffer;
1458
1459	ZERO_STRUCT(q);
1460	ZERO_STRUCT(r);
1461
1462	/* Initialise parse structures */
1463
1464	init_buffer(&buffer, offered, mem_ctx);
1465
1466	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1467	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1468
1469	/* Initialise input parameters */
1470
1471        make_spoolss_q_enumforms(&q, handle, level, &buffer, offered);
1472
1473	/* Marshall data and send request */
1474
1475	if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) ||
1476	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
1477		goto done;
1478
1479	/* Unmarshall response */
1480
1481	if (!spoolss_io_r_enumforms("", &r, &rbuf, 0))
1482		goto done;
1483
1484	/* Return output parameters */
1485
1486	result = r.status;
1487
1488	if (needed)
1489		*needed = r.needed;
1490
1491	if (num_forms)
1492		*num_forms = r.numofforms;
1493
1494	decode_forms_1(mem_ctx, r.buffer, *num_forms, forms);
1495
1496 done:
1497	prs_mem_free(&qbuf);
1498	prs_mem_free(&rbuf);
1499
1500	return result;
1501}
1502
1503static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
1504			  uint32 num_jobs, JOB_INFO_1 **jobs)
1505{
1506	uint32 i;
1507
1508	*jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1));
1509	prs_set_offset(&buffer->prs,0);
1510
1511	for (i = 0; i < num_jobs; i++)
1512		smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
1513}
1514
1515static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
1516			  uint32 num_jobs, JOB_INFO_2 **jobs)
1517{
1518	uint32 i;
1519
1520	*jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2));
1521	prs_set_offset(&buffer->prs,0);
1522
1523	for (i = 0; i < num_jobs; i++)
1524		smb_io_job_info_2("", buffer, &((*jobs)[i]), 0);
1525}
1526
1527/* Enumerate jobs */
1528
1529WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1530			    uint32 offered, uint32 *needed,
1531			    POLICY_HND *hnd, uint32 level, uint32 firstjob,
1532			    uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
1533{
1534	prs_struct qbuf, rbuf;
1535	SPOOL_Q_ENUMJOBS q;
1536	SPOOL_R_ENUMJOBS r;
1537	WERROR result = W_ERROR(ERRgeneral);
1538	NEW_BUFFER buffer;
1539
1540	ZERO_STRUCT(q);
1541	ZERO_STRUCT(r);
1542
1543	/* Initialise parse structures */
1544
1545	init_buffer(&buffer, offered, mem_ctx);
1546
1547	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1548	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1549
1550	/* Initialise input parameters */
1551
1552        make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer,
1553				offered);
1554
1555	/* Marshall data and send request */
1556
1557	if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) ||
1558	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf))
1559		goto done;
1560
1561	/* Unmarshall response */
1562
1563	if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0))
1564		goto done;
1565
1566	/* Return output parameters */
1567
1568	result = r.status;
1569
1570	if (needed)
1571		*needed = r.needed;
1572
1573	if (!W_ERROR_IS_OK(r.status))
1574		goto done;
1575
1576	*returned = r.returned;
1577
1578	switch(level) {
1579	case 1:
1580		decode_jobs_1(mem_ctx, r.buffer, r.returned,
1581			      &ctr->job.job_info_1);
1582		break;
1583	case 2:
1584		decode_jobs_2(mem_ctx, r.buffer, r.returned,
1585			      &ctr->job.job_info_2);
1586		break;
1587	default:
1588		DEBUG(3, ("unsupported info level %d", level));
1589		break;
1590	}
1591
1592 done:
1593	prs_mem_free(&qbuf);
1594	prs_mem_free(&rbuf);
1595
1596	return result;
1597}
1598
1599/* Set job */
1600
1601WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1602			  POLICY_HND *hnd, uint32 jobid, uint32 level,
1603			  uint32 command)
1604{
1605	prs_struct qbuf, rbuf;
1606	SPOOL_Q_SETJOB q;
1607	SPOOL_R_SETJOB r;
1608	WERROR result = W_ERROR(ERRgeneral);
1609
1610	ZERO_STRUCT(q);
1611	ZERO_STRUCT(r);
1612
1613	/* Initialise parse structures */
1614
1615	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1616	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1617
1618	/* Initialise input parameters */
1619
1620        make_spoolss_q_setjob(&q, hnd, jobid, level, command);
1621
1622	/* Marshall data and send request */
1623
1624	if (!spoolss_io_q_setjob("", &q, &qbuf, 0) ||
1625	    !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf))
1626		goto done;
1627
1628	/* Unmarshall response */
1629
1630	if (!spoolss_io_r_setjob("", &r, &rbuf, 0))
1631		goto done;
1632
1633	/* Return output parameters */
1634
1635	result = r.status;
1636
1637 done:
1638	prs_mem_free(&qbuf);
1639	prs_mem_free(&rbuf);
1640
1641	return result;
1642}
1643
1644/* Get job */
1645
1646WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1647			  uint32 offered, uint32 *needed,
1648			  POLICY_HND *hnd, uint32 jobid, uint32 level,
1649			  JOB_INFO_CTR *ctr)
1650{
1651	prs_struct qbuf, rbuf;
1652	SPOOL_Q_GETJOB q;
1653	SPOOL_R_GETJOB r;
1654	WERROR result = W_ERROR(ERRgeneral);
1655	NEW_BUFFER buffer;
1656
1657	ZERO_STRUCT(q);
1658	ZERO_STRUCT(r);
1659
1660	/* Initialise parse structures */
1661
1662	init_buffer(&buffer, offered, mem_ctx);
1663
1664	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1665	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1666
1667	/* Initialise input parameters */
1668
1669        make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered);
1670
1671	/* Marshall data and send request */
1672
1673	if (!spoolss_io_q_getjob("", &q, &qbuf, 0) ||
1674	    !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf))
1675		goto done;
1676
1677	/* Unmarshall response */
1678
1679	if (!spoolss_io_r_getjob("", &r, &rbuf, 0))
1680		goto done;
1681
1682	/* Return output parameters */
1683
1684	result = r.status;
1685
1686	if (needed)
1687		*needed = r.needed;
1688
1689	if (!W_ERROR_IS_OK(r.status))
1690		goto done;
1691
1692	switch(level) {
1693	case 1:
1694		decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1);
1695		break;
1696	case 2:
1697		decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2);
1698		break;
1699	default:
1700		DEBUG(3, ("unsupported info level %d", level));
1701		break;
1702	}
1703
1704 done:
1705	prs_mem_free(&qbuf);
1706	prs_mem_free(&rbuf);
1707
1708	return result;
1709}
1710
1711/* Startpageprinter.  Sent to notify the spooler when a page is about to be
1712   sent to a printer. */
1713
1714WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1715				    POLICY_HND *hnd)
1716{
1717	prs_struct qbuf, rbuf;
1718	SPOOL_Q_STARTPAGEPRINTER q;
1719	SPOOL_R_STARTPAGEPRINTER r;
1720	WERROR result = W_ERROR(ERRgeneral);
1721
1722	ZERO_STRUCT(q);
1723	ZERO_STRUCT(r);
1724
1725	/* Initialise parse structures */
1726
1727	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1728	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1729
1730	/* Initialise input parameters */
1731
1732        make_spoolss_q_startpageprinter(&q, hnd);
1733
1734	/* Marshall data and send request */
1735
1736	if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) ||
1737	    !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf))
1738		goto done;
1739
1740	/* Unmarshall response */
1741
1742	if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0))
1743		goto done;
1744
1745	/* Return output parameters */
1746
1747	result = r.status;
1748
1749 done:
1750	prs_mem_free(&qbuf);
1751	prs_mem_free(&rbuf);
1752
1753	return result;
1754}
1755
1756/* Endpageprinter.  Sent to notify the spooler when a page has finished
1757   being sent to a printer. */
1758
1759WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1760				  POLICY_HND *hnd)
1761{
1762	prs_struct qbuf, rbuf;
1763	SPOOL_Q_ENDPAGEPRINTER q;
1764	SPOOL_R_ENDPAGEPRINTER r;
1765	WERROR result = W_ERROR(ERRgeneral);
1766
1767	ZERO_STRUCT(q);
1768	ZERO_STRUCT(r);
1769
1770	/* Initialise parse structures */
1771
1772	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1773	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1774
1775	/* Initialise input parameters */
1776
1777        make_spoolss_q_endpageprinter(&q, hnd);
1778
1779	/* Marshall data and send request */
1780
1781	if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) ||
1782	    !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf))
1783		goto done;
1784
1785	/* Unmarshall response */
1786
1787	if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0))
1788		goto done;
1789
1790	/* Return output parameters */
1791
1792	result = r.status;
1793
1794 done:
1795	prs_mem_free(&qbuf);
1796	prs_mem_free(&rbuf);
1797
1798	return result;
1799}
1800
1801/* Startdocprinter.  Sent to notify the spooler that a document is about
1802   to be spooled for printing. */
1803
1804WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1805				   POLICY_HND *hnd, char *docname,
1806				   char *outputfile, char *datatype,
1807				   uint32 *jobid)
1808{
1809	prs_struct qbuf, rbuf;
1810	SPOOL_Q_STARTDOCPRINTER q;
1811	SPOOL_R_STARTDOCPRINTER r;
1812	WERROR result = W_ERROR(ERRgeneral);
1813	uint32 level = 1;
1814
1815	ZERO_STRUCT(q);
1816	ZERO_STRUCT(r);
1817
1818	/* Initialise parse structures */
1819
1820	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1821	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1822
1823	/* Initialise input parameters */
1824
1825        make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile,
1826				       datatype);
1827
1828	/* Marshall data and send request */
1829
1830	if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) ||
1831	    !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf))
1832		goto done;
1833
1834	/* Unmarshall response */
1835
1836	if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0))
1837		goto done;
1838
1839	/* Return output parameters */
1840
1841	result = r.status;
1842
1843	if (W_ERROR_IS_OK(result))
1844		*jobid = r.jobid;
1845
1846 done:
1847	prs_mem_free(&qbuf);
1848	prs_mem_free(&rbuf);
1849
1850	return result;
1851}
1852
1853/* Enddocprinter.  Sent to notify the spooler that a document has finished
1854   being spooled. */
1855
1856WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1857				  POLICY_HND *hnd)
1858{
1859	prs_struct qbuf, rbuf;
1860	SPOOL_Q_ENDDOCPRINTER q;
1861	SPOOL_R_ENDDOCPRINTER r;
1862	WERROR result = W_ERROR(ERRgeneral);
1863
1864	ZERO_STRUCT(q);
1865	ZERO_STRUCT(r);
1866
1867	/* Initialise parse structures */
1868
1869	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1870	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1871
1872	/* Initialise input parameters */
1873
1874        make_spoolss_q_enddocprinter(&q, hnd);
1875
1876	/* Marshall data and send request */
1877
1878	if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) ||
1879	    !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf))
1880		goto done;
1881
1882	/* Unmarshall response */
1883
1884	if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0))
1885		goto done;
1886
1887	/* Return output parameters */
1888
1889	result = r.status;
1890
1891 done:
1892	prs_mem_free(&qbuf);
1893	prs_mem_free(&rbuf);
1894
1895	return result;
1896}
1897
1898/* Get printer data */
1899
1900WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1901				  uint32 offered, uint32 *needed,
1902				  POLICY_HND *hnd, const char *valuename,
1903				  REGISTRY_VALUE *value)
1904{
1905	prs_struct qbuf, rbuf;
1906	SPOOL_Q_GETPRINTERDATA q;
1907	SPOOL_R_GETPRINTERDATA r;
1908	WERROR result = W_ERROR(ERRgeneral);
1909
1910	ZERO_STRUCT(q);
1911	ZERO_STRUCT(r);
1912
1913	/* Initialise parse structures */
1914
1915	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1916	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1917
1918	/* Initialise input parameters */
1919
1920        make_spoolss_q_getprinterdata(&q, hnd, valuename, offered);
1921
1922	/* Marshall data and send request */
1923
1924	if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) ||
1925	    !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
1926		goto done;
1927
1928	/* Unmarshall response */
1929
1930	if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0))
1931		goto done;
1932
1933	result = r.status;
1934
1935	if (needed)
1936		*needed = r.needed;
1937
1938	if (!W_ERROR_IS_OK(r.status))
1939		goto done;
1940
1941	/* Return output parameters */
1942
1943	value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
1944	value->type = r.type;
1945	value->size = r.size;
1946
1947 done:
1948	prs_mem_free(&qbuf);
1949	prs_mem_free(&rbuf);
1950
1951	return result;
1952}
1953
1954WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1955				    uint32 offered, uint32 *needed,
1956				    POLICY_HND *hnd, const char *keyname,
1957				    const char *valuename,
1958				    REGISTRY_VALUE *value)
1959{
1960	prs_struct qbuf, rbuf;
1961	SPOOL_Q_GETPRINTERDATAEX q;
1962	SPOOL_R_GETPRINTERDATAEX r;
1963	WERROR result = W_ERROR(ERRgeneral);
1964
1965	ZERO_STRUCT(q);
1966	ZERO_STRUCT(r);
1967
1968	/* Initialise parse structures */
1969
1970	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1971	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1972
1973	/* Initialise input parameters */
1974
1975        make_spoolss_q_getprinterdataex(&q, hnd, keyname, valuename, offered);
1976
1977	/* Marshall data and send request */
1978
1979	if (!spoolss_io_q_getprinterdataex("", &q, &qbuf, 0) ||
1980	    !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf))
1981		goto done;
1982
1983	/* Unmarshall response */
1984
1985	if (!spoolss_io_r_getprinterdataex("", &r, &rbuf, 0))
1986		goto done;
1987
1988	result = r.status;
1989
1990	if (needed)
1991		*needed = r.needed;
1992
1993	if (!W_ERROR_IS_OK(r.status))
1994		goto done;
1995
1996	/* Return output parameters */
1997
1998	value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
1999	value->type = r.type;
2000	value->size = r.needed;
2001
2002 done:
2003	prs_mem_free(&qbuf);
2004	prs_mem_free(&rbuf);
2005
2006	return result;
2007}
2008
2009/* Set printer data */
2010
2011WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2012				  POLICY_HND *hnd, REGISTRY_VALUE *value)
2013{
2014	prs_struct qbuf, rbuf;
2015	SPOOL_Q_SETPRINTERDATA q;
2016	SPOOL_R_SETPRINTERDATA r;
2017	WERROR result = W_ERROR(ERRgeneral);
2018
2019	ZERO_STRUCT(q);
2020	ZERO_STRUCT(r);
2021
2022	/* Initialise parse structures */
2023
2024	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2025	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2026
2027	/* Initialise input parameters */
2028
2029        make_spoolss_q_setprinterdata(
2030		&q, hnd, value->valuename, value->type, (char *)value->data_p, value->size);
2031
2032	/* Marshall data and send request */
2033
2034	if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) ||
2035	    !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
2036		goto done;
2037
2038	/* Unmarshall response */
2039
2040	if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0))
2041		goto done;
2042
2043	result = r.status;
2044
2045	if (!W_ERROR_IS_OK(r.status))
2046		goto done;
2047
2048 done:
2049	prs_mem_free(&qbuf);
2050	prs_mem_free(&rbuf);
2051
2052	return result;
2053}
2054
2055WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2056				    POLICY_HND *hnd, char *keyname,
2057				    REGISTRY_VALUE *value)
2058{
2059	prs_struct qbuf, rbuf;
2060	SPOOL_Q_SETPRINTERDATAEX q;
2061	SPOOL_R_SETPRINTERDATAEX r;
2062	WERROR result = W_ERROR(ERRgeneral);
2063
2064	ZERO_STRUCT(q);
2065	ZERO_STRUCT(r);
2066
2067	/* Initialise parse structures */
2068
2069	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2070	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2071
2072	/* Initialise input parameters */
2073
2074        make_spoolss_q_setprinterdataex(
2075		&q, hnd, keyname, value->valuename, value->type, (char *)value->data_p,
2076		value->size);
2077
2078	/* Marshall data and send request */
2079
2080	if (!spoolss_io_q_setprinterdataex("", &q, &qbuf, 0) ||
2081	    !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf))
2082		goto done;
2083
2084	/* Unmarshall response */
2085
2086	if (!spoolss_io_r_setprinterdataex("", &r, &rbuf, 0))
2087		goto done;
2088
2089	result = r.status;
2090
2091	if (!W_ERROR_IS_OK(r.status))
2092		goto done;
2093
2094 done:
2095	prs_mem_free(&qbuf);
2096	prs_mem_free(&rbuf);
2097
2098	return result;
2099}
2100
2101/* Enum printer data */
2102
2103WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2104				   POLICY_HND *hnd, uint32 ndx,
2105				   uint32 value_offered, uint32 data_offered,
2106				   uint32 *value_needed, uint32 *data_needed,
2107				   REGISTRY_VALUE *value)
2108{
2109	prs_struct qbuf, rbuf;
2110	SPOOL_Q_ENUMPRINTERDATA q;
2111	SPOOL_R_ENUMPRINTERDATA r;
2112	WERROR result = W_ERROR(ERRgeneral);
2113
2114	ZERO_STRUCT(q);
2115	ZERO_STRUCT(r);
2116
2117	/* Initialise parse structures */
2118
2119	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2120	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2121
2122	/* Initialise input parameters */
2123
2124        make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered);
2125
2126	/* Marshall data and send request */
2127
2128	if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) ||
2129	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf))
2130		goto done;
2131
2132	/* Unmarshall response */
2133
2134	if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0))
2135		goto done;
2136
2137	result = r.status;
2138
2139	if (!W_ERROR_IS_OK(r.status))
2140		goto done;
2141
2142	/* Return data */
2143
2144	if (value_needed)
2145		*value_needed = r.realvaluesize;
2146
2147	if (data_needed)
2148		*data_needed = r.realdatasize;
2149
2150	if (value) {
2151		rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1,
2152			    STR_TERMINATE);
2153		value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize);
2154		value->type = r.type;
2155		value->size = r.realdatasize;
2156	}
2157
2158 done:
2159	prs_mem_free(&qbuf);
2160	prs_mem_free(&rbuf);
2161
2162	return result;
2163}
2164
2165WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2166				     uint32 offered, uint32 *needed,
2167				     POLICY_HND *hnd, const char *keyname,
2168				     REGVAL_CTR *ctr)
2169{
2170	prs_struct qbuf, rbuf;
2171	SPOOL_Q_ENUMPRINTERDATAEX q;
2172	SPOOL_R_ENUMPRINTERDATAEX r;
2173	WERROR result = W_ERROR(ERRgeneral);
2174	int i;
2175
2176	ZERO_STRUCT(q);
2177	ZERO_STRUCT(r);
2178
2179	/* Initialise parse structures */
2180
2181	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2182	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2183
2184	/* Initialise input parameters */
2185
2186        make_spoolss_q_enumprinterdataex(&q, hnd, keyname, offered);
2187
2188	/* Marshall data and send request */
2189
2190	if (!spoolss_io_q_enumprinterdataex("", &q, &qbuf, 0) ||
2191	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf))
2192		goto done;
2193
2194	/* Unmarshall response */
2195
2196	if (!spoolss_io_r_enumprinterdataex("", &r, &rbuf, 0))
2197		goto done;
2198
2199	result = r.status;
2200
2201	if (needed)
2202		*needed = r.needed;
2203
2204	if (!W_ERROR_IS_OK(r.status))
2205		goto done;
2206
2207	/* Return data */
2208
2209	ZERO_STRUCTP(ctr);
2210	regval_ctr_init(ctr);
2211
2212	for (i = 0; i < r.returned; i++) {
2213		PRINTER_ENUM_VALUES *v = &r.ctr.values[i];
2214		fstring name;
2215
2216		rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1,
2217			    STR_TERMINATE);
2218		regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
2219	}
2220
2221 done:
2222	prs_mem_free(&qbuf);
2223	prs_mem_free(&rbuf);
2224
2225	return result;
2226}
2227
2228/* Write data to printer */
2229
2230WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2231				POLICY_HND *hnd, uint32 data_size, char *data,
2232				uint32 *num_written)
2233{
2234	prs_struct qbuf, rbuf;
2235	SPOOL_Q_WRITEPRINTER q;
2236	SPOOL_R_WRITEPRINTER r;
2237	WERROR result = W_ERROR(ERRgeneral);
2238
2239	ZERO_STRUCT(q);
2240	ZERO_STRUCT(r);
2241
2242	/* Initialise parse structures */
2243
2244	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2245	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2246
2247	/* Initialise input parameters */
2248
2249        make_spoolss_q_writeprinter(&q, hnd, data_size, data);
2250
2251	/* Marshall data and send request */
2252
2253	if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
2254	    !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
2255		goto done;
2256
2257	/* Unmarshall response */
2258
2259	if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0))
2260		goto done;
2261
2262	result = r.status;
2263
2264	if (!W_ERROR_IS_OK(r.status))
2265		goto done;
2266
2267	if (num_written)
2268		*num_written = r.buffer_written;
2269
2270 done:
2271	prs_mem_free(&qbuf);
2272	prs_mem_free(&rbuf);
2273
2274	return result;
2275}
2276
2277/* Delete printer data */
2278
2279WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2280				     POLICY_HND *hnd, char *valuename)
2281{
2282	prs_struct qbuf, rbuf;
2283	SPOOL_Q_DELETEPRINTERDATA q;
2284	SPOOL_R_DELETEPRINTERDATA r;
2285	WERROR result = W_ERROR(ERRgeneral);
2286
2287	ZERO_STRUCT(q);
2288	ZERO_STRUCT(r);
2289
2290	/* Initialise parse structures */
2291
2292	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2293	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2294
2295	/* Initialise input parameters */
2296
2297        make_spoolss_q_deleteprinterdata(&q, hnd, valuename);
2298
2299	/* Marshall data and send request */
2300
2301	if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) ||
2302	    !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf))
2303		goto done;
2304
2305	/* Unmarshall response */
2306
2307	if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0))
2308		goto done;
2309
2310	result = r.status;
2311
2312	if (!W_ERROR_IS_OK(r.status))
2313		goto done;
2314
2315 done:
2316	prs_mem_free(&qbuf);
2317	prs_mem_free(&rbuf);
2318
2319	return result;
2320}
2321
2322WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2323				       POLICY_HND *hnd, char *keyname,
2324				       char *valuename)
2325{
2326	prs_struct qbuf, rbuf;
2327	SPOOL_Q_DELETEPRINTERDATAEX q;
2328	SPOOL_R_DELETEPRINTERDATAEX r;
2329	WERROR result = W_ERROR(ERRgeneral);
2330
2331	ZERO_STRUCT(q);
2332	ZERO_STRUCT(r);
2333
2334	/* Initialise parse structures */
2335
2336	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2337	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2338
2339	/* Initialise input parameters */
2340
2341        make_spoolss_q_deleteprinterdataex(&q, hnd, keyname, valuename);
2342
2343	/* Marshall data and send request */
2344
2345	if (!spoolss_io_q_deleteprinterdataex("", &q, &qbuf, 0) ||
2346	    !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf))
2347		goto done;
2348
2349	/* Unmarshall response */
2350
2351	if (!spoolss_io_r_deleteprinterdataex("", &r, &rbuf, 0))
2352		goto done;
2353
2354	result = r.status;
2355
2356	if (!W_ERROR_IS_OK(r.status))
2357		goto done;
2358
2359 done:
2360	prs_mem_free(&qbuf);
2361	prs_mem_free(&rbuf);
2362
2363	return result;
2364}
2365
2366WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2367				  uint32 offered, uint32 *needed,
2368				  POLICY_HND *hnd, const char *keyname,
2369				  uint16 **keylist, uint32 *len)
2370{
2371	prs_struct qbuf, rbuf;
2372	SPOOL_Q_ENUMPRINTERKEY q;
2373	SPOOL_R_ENUMPRINTERKEY r;
2374	WERROR result = W_ERROR(ERRgeneral);
2375
2376	ZERO_STRUCT(q);
2377	ZERO_STRUCT(r);
2378
2379	/* Initialise parse structures */
2380
2381	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2382	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2383
2384	/* Initialise input parameters */
2385
2386        make_spoolss_q_enumprinterkey(&q, hnd, keyname, offered);
2387
2388	/* Marshall data and send request */
2389
2390	if (!spoolss_io_q_enumprinterkey("", &q, &qbuf, 0) ||
2391	    !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERKEY, &qbuf, &rbuf))
2392		goto done;
2393
2394	/* Unmarshall response */
2395
2396	if (!spoolss_io_r_enumprinterkey("", &r, &rbuf, 0))
2397		goto done;
2398
2399	result = r.status;
2400
2401	if (needed)
2402		*needed = r.needed;
2403
2404	if (!W_ERROR_IS_OK(r.status))
2405		goto done;
2406
2407	/* Copy results */
2408
2409	if (keylist) {
2410		*keylist = (uint16 *)malloc(r.keys.buf_len * 2);
2411		memcpy(*keylist, r.keys.buffer, r.keys.buf_len * 2);
2412		if (len)
2413			*len = r.keys.buf_len * 2;
2414	}
2415
2416 done:
2417	prs_mem_free(&qbuf);
2418	prs_mem_free(&rbuf);
2419
2420	return result;
2421}
2422
2423WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2424				    POLICY_HND *hnd, char *keyname)
2425{
2426	prs_struct qbuf, rbuf;
2427	SPOOL_Q_DELETEPRINTERKEY q;
2428	SPOOL_R_DELETEPRINTERKEY r;
2429	WERROR result = W_ERROR(ERRgeneral);
2430
2431	ZERO_STRUCT(q);
2432	ZERO_STRUCT(r);
2433
2434	/* Initialise parse structures */
2435
2436	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2437	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2438
2439	/* Initialise input parameters */
2440
2441        make_spoolss_q_deleteprinterkey(&q, hnd, keyname);
2442
2443	/* Marshall data and send request */
2444
2445	if (!spoolss_io_q_deleteprinterkey("", &q, &qbuf, 0) ||
2446	    !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERKEY, &qbuf, &rbuf))
2447		goto done;
2448
2449	/* Unmarshall response */
2450
2451	if (!spoolss_io_r_deleteprinterkey("", &r, &rbuf, 0))
2452		goto done;
2453
2454	result = r.status;
2455
2456	if (!W_ERROR_IS_OK(r.status))
2457		goto done;
2458
2459 done:
2460	prs_mem_free(&qbuf);
2461	prs_mem_free(&rbuf);
2462
2463	return result;
2464}
2465
2466/** @} **/
2467