cli_spoolss_enumprinterdrivers:
[ira/wip.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                 default:
852                         DEBUG(10, ("cli_spoolss_enumprinterdrivers: unknown info level %d\n",
853                                    level));
854                         return WERR_UNKNOWN_LEVEL;
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                                   REGISTRY_VALUE *value)
1882 {
1883         prs_struct qbuf, rbuf;
1884         SPOOL_Q_GETPRINTERDATA q;
1885         SPOOL_R_GETPRINTERDATA r;
1886         WERROR result = W_ERROR(ERRgeneral);
1887
1888         ZERO_STRUCT(q);
1889         ZERO_STRUCT(r);
1890
1891         /* Initialise parse structures */
1892
1893         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1894         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1895
1896         /* Initialise input parameters */
1897
1898         make_spoolss_q_getprinterdata(&q, hnd, valuename, offered);
1899
1900         /* Marshall data and send request */
1901
1902         if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) ||
1903             !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
1904                 goto done;
1905
1906         /* Unmarshall response */
1907
1908         if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0))
1909                 goto done;
1910         
1911         result = r.status;
1912
1913         if (needed)
1914                 *needed = r.needed;
1915
1916         if (!W_ERROR_IS_OK(r.status))
1917                 goto done;      
1918
1919         /* Return output parameters */
1920
1921         value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
1922         value->type = r.type;
1923         value->size = r.size;
1924
1925  done:
1926         prs_mem_free(&qbuf);
1927         prs_mem_free(&rbuf);
1928
1929         return result;
1930 }
1931
1932 WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1933                                     uint32 offered, uint32 *needed,
1934                                     POLICY_HND *hnd, char *keyname, 
1935                                     char *valuename, REGISTRY_VALUE *value)
1936 {
1937         prs_struct qbuf, rbuf;
1938         SPOOL_Q_GETPRINTERDATAEX q;
1939         SPOOL_R_GETPRINTERDATAEX r;
1940         WERROR result = W_ERROR(ERRgeneral);
1941
1942         ZERO_STRUCT(q);
1943         ZERO_STRUCT(r);
1944
1945         /* Initialise parse structures */
1946
1947         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1948         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1949
1950         /* Initialise input parameters */
1951
1952         make_spoolss_q_getprinterdataex(&q, hnd, keyname, valuename, offered);
1953
1954         /* Marshall data and send request */
1955
1956         if (!spoolss_io_q_getprinterdataex("", &q, &qbuf, 0) ||
1957             !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf))
1958                 goto done;
1959
1960         /* Unmarshall response */
1961
1962         if (!spoolss_io_r_getprinterdataex("", &r, &rbuf, 0))
1963                 goto done;
1964         
1965         result = r.status;
1966
1967         if (needed)
1968                 *needed = r.needed;
1969
1970         if (!W_ERROR_IS_OK(r.status))
1971                 goto done;      
1972
1973         /* Return output parameters */
1974
1975         value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
1976         value->type = r.type;
1977         value->size = r.needed;
1978
1979  done:
1980         prs_mem_free(&qbuf);
1981         prs_mem_free(&rbuf);
1982
1983         return result;
1984 }
1985
1986 /* Set printer data */
1987
1988 WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1989                                   POLICY_HND *hnd, REGISTRY_VALUE *value)
1990 {
1991         prs_struct qbuf, rbuf;
1992         SPOOL_Q_SETPRINTERDATA q;
1993         SPOOL_R_SETPRINTERDATA r;
1994         WERROR result = W_ERROR(ERRgeneral);
1995
1996         ZERO_STRUCT(q);
1997         ZERO_STRUCT(r);
1998
1999         /* Initialise parse structures */
2000
2001         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2002         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2003
2004         /* Initialise input parameters */
2005
2006         make_spoolss_q_setprinterdata(
2007                 &q, hnd, value->valuename, value->type, value->data_p, value->size);
2008
2009         /* Marshall data and send request */
2010
2011         if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) ||
2012             !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
2013                 goto done;
2014
2015         /* Unmarshall response */
2016
2017         if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0))
2018                 goto done;
2019         
2020         result = r.status;
2021
2022         if (!W_ERROR_IS_OK(r.status))
2023                 goto done;      
2024
2025  done:
2026         prs_mem_free(&qbuf);
2027         prs_mem_free(&rbuf);
2028
2029         return result;
2030 }
2031
2032 WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2033                                     POLICY_HND *hnd, char *keyname, 
2034                                     REGISTRY_VALUE *value)
2035 {
2036         prs_struct qbuf, rbuf;
2037         SPOOL_Q_SETPRINTERDATAEX q;
2038         SPOOL_R_SETPRINTERDATAEX r;
2039         WERROR result = W_ERROR(ERRgeneral);
2040
2041         ZERO_STRUCT(q);
2042         ZERO_STRUCT(r);
2043
2044         /* Initialise parse structures */
2045
2046         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2047         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2048
2049         /* Initialise input parameters */
2050
2051         make_spoolss_q_setprinterdataex(
2052                 &q, hnd, keyname, value->valuename, value->type, value->data_p, 
2053                 value->size);
2054
2055         /* Marshall data and send request */
2056
2057         if (!spoolss_io_q_setprinterdataex("", &q, &qbuf, 0) ||
2058             !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf))
2059                 goto done;
2060
2061         /* Unmarshall response */
2062
2063         if (!spoolss_io_r_setprinterdataex("", &r, &rbuf, 0))
2064                 goto done;
2065         
2066         result = r.status;
2067
2068         if (!W_ERROR_IS_OK(r.status))
2069                 goto done;      
2070
2071  done:
2072         prs_mem_free(&qbuf);
2073         prs_mem_free(&rbuf);
2074
2075         return result;
2076 }
2077
2078 /* Enum printer data */
2079
2080 WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2081                                    POLICY_HND *hnd, uint32 ndx,
2082                                    uint32 value_offered, uint32 data_offered,
2083                                    uint32 *value_needed, uint32 *data_needed,
2084                                    REGISTRY_VALUE *value)
2085 {
2086         prs_struct qbuf, rbuf;
2087         SPOOL_Q_ENUMPRINTERDATA q;
2088         SPOOL_R_ENUMPRINTERDATA r;
2089         WERROR result = W_ERROR(ERRgeneral);
2090
2091         ZERO_STRUCT(q);
2092         ZERO_STRUCT(r);
2093
2094         /* Initialise parse structures */
2095
2096         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2097         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2098
2099         /* Initialise input parameters */
2100
2101         make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered);
2102
2103         /* Marshall data and send request */
2104
2105         if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) ||
2106             !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf))
2107                 goto done;
2108
2109         /* Unmarshall response */
2110
2111         if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0))
2112                 goto done;
2113         
2114         result = r.status;
2115
2116         if (!W_ERROR_IS_OK(r.status))
2117                 goto done;
2118
2119         /* Return data */
2120         
2121         if (value_needed)
2122                 *value_needed = r.realvaluesize;
2123
2124         if (data_needed)
2125                 *data_needed = r.realdatasize;
2126
2127         if (value) {
2128                 rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1,
2129                             STR_TERMINATE);
2130                 value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize);
2131                 value->type = r.type;
2132                 value->size = r.realdatasize;
2133         }
2134
2135  done:
2136         prs_mem_free(&qbuf);
2137         prs_mem_free(&rbuf);
2138
2139         return result;
2140 }
2141
2142 WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2143                                      uint32 offered, uint32 *needed,
2144                                      POLICY_HND *hnd, char *keyname, 
2145                                      REGVAL_CTR *ctr)
2146 {
2147         prs_struct qbuf, rbuf;
2148         SPOOL_Q_ENUMPRINTERDATAEX q;
2149         SPOOL_R_ENUMPRINTERDATAEX r;
2150         WERROR result = W_ERROR(ERRgeneral);
2151         int i;
2152
2153         ZERO_STRUCT(q);
2154         ZERO_STRUCT(r);
2155
2156         /* Initialise parse structures */
2157
2158         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2159         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2160
2161         /* Initialise input parameters */
2162
2163         make_spoolss_q_enumprinterdataex(&q, hnd, keyname, offered);
2164
2165         /* Marshall data and send request */
2166
2167         if (!spoolss_io_q_enumprinterdataex("", &q, &qbuf, 0) ||
2168             !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf))
2169                 goto done;
2170
2171         /* Unmarshall response */
2172
2173         if (!spoolss_io_r_enumprinterdataex("", &r, &rbuf, 0))
2174                 goto done;
2175         
2176         result = r.status;
2177         
2178         if (needed)
2179                 *needed = r.needed;
2180         
2181         if (!W_ERROR_IS_OK(r.status))
2182                 goto done;
2183
2184         /* Return data */
2185
2186         ZERO_STRUCTP(ctr);
2187         regval_ctr_init(ctr);
2188
2189         for (i = 0; i < r.returned; i++) {
2190                 PRINTER_ENUM_VALUES *v = &r.ctr.values[i];
2191                 fstring name;
2192
2193                 rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, 
2194                             STR_TERMINATE);
2195                 regval_ctr_addvalue(ctr, name, v->type, v->data, v->data_len);
2196         }
2197
2198  done:
2199         prs_mem_free(&qbuf);
2200         prs_mem_free(&rbuf);
2201
2202         return result;
2203 }
2204
2205 /* Write data to printer */
2206
2207 WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2208                                 POLICY_HND *hnd, uint32 data_size, char *data,
2209                                 uint32 *num_written)
2210 {
2211         prs_struct qbuf, rbuf;
2212         SPOOL_Q_WRITEPRINTER q;
2213         SPOOL_R_WRITEPRINTER r;
2214         WERROR result = W_ERROR(ERRgeneral);
2215
2216         ZERO_STRUCT(q);
2217         ZERO_STRUCT(r);
2218
2219         /* Initialise parse structures */
2220
2221         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2222         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2223
2224         /* Initialise input parameters */
2225
2226         make_spoolss_q_writeprinter(&q, hnd, data_size, data);
2227
2228         /* Marshall data and send request */
2229
2230         if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
2231             !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
2232                 goto done;
2233
2234         /* Unmarshall response */
2235
2236         if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0))
2237                 goto done;
2238         
2239         result = r.status;
2240
2241         if (!W_ERROR_IS_OK(r.status))
2242                 goto done;      
2243
2244         if (num_written)
2245                 *num_written = r.buffer_written;
2246
2247  done:
2248         prs_mem_free(&qbuf);
2249         prs_mem_free(&rbuf);
2250
2251         return result;
2252 }
2253
2254 /* Delete printer data */
2255
2256 WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2257                                      POLICY_HND *hnd, char *valuename)
2258 {
2259         prs_struct qbuf, rbuf;
2260         SPOOL_Q_DELETEPRINTERDATA q;
2261         SPOOL_R_DELETEPRINTERDATA r;
2262         WERROR result = W_ERROR(ERRgeneral);
2263
2264         ZERO_STRUCT(q);
2265         ZERO_STRUCT(r);
2266
2267         /* Initialise parse structures */
2268
2269         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2270         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2271
2272         /* Initialise input parameters */
2273
2274         make_spoolss_q_deleteprinterdata(&q, hnd, valuename);
2275
2276         /* Marshall data and send request */
2277
2278         if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) ||
2279             !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf))
2280                 goto done;
2281
2282         /* Unmarshall response */
2283
2284         if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0))
2285                 goto done;
2286         
2287         result = r.status;
2288
2289         if (!W_ERROR_IS_OK(r.status))
2290                 goto done;      
2291
2292  done:
2293         prs_mem_free(&qbuf);
2294         prs_mem_free(&rbuf);
2295
2296         return result;
2297 }
2298
2299 WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2300                                        POLICY_HND *hnd, char *keyname, 
2301                                        char *valuename)
2302 {
2303         prs_struct qbuf, rbuf;
2304         SPOOL_Q_DELETEPRINTERDATAEX q;
2305         SPOOL_R_DELETEPRINTERDATAEX r;
2306         WERROR result = W_ERROR(ERRgeneral);
2307
2308         ZERO_STRUCT(q);
2309         ZERO_STRUCT(r);
2310
2311         /* Initialise parse structures */
2312
2313         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2314         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2315
2316         /* Initialise input parameters */
2317
2318         make_spoolss_q_deleteprinterdataex(&q, hnd, keyname, valuename);
2319
2320         /* Marshall data and send request */
2321
2322         if (!spoolss_io_q_deleteprinterdataex("", &q, &qbuf, 0) ||
2323             !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf))
2324                 goto done;
2325
2326         /* Unmarshall response */
2327
2328         if (!spoolss_io_r_deleteprinterdataex("", &r, &rbuf, 0))
2329                 goto done;
2330         
2331         result = r.status;
2332
2333         if (!W_ERROR_IS_OK(r.status))
2334                 goto done;      
2335
2336  done:
2337         prs_mem_free(&qbuf);
2338         prs_mem_free(&rbuf);
2339
2340         return result;
2341 }
2342
2343 /** @} **/