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