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