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