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