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