28f4f481fadc8f070042b3e1127707267133bc29
[kai/samba.git] / source3 / libsmb / cli_spoolss.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Gerald Carter                2001-2002,
6    Copyright (C) Tim Potter                   2000-2002,
7    Copyright (C) Andrew Tridgell              1994-2000,
8    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
9    Copyright (C) Jean-Francois Micouleau      1999-2000.
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 /** @defgroup spoolss SPOOLSS - NT printing routines
29  *  @ingroup rpc_client
30  *
31  * @{
32  **/
33
34 /** Opens a SMB connection and connects to the SPOOLSS pipe.
35  *
36  * @param cli Uninitialised client handle.
37  * @param system_name NETBIOS name of the machine to connect to.
38  * @param creds User credentials to connect as.
39  * @returns Initialised client handle.
40  */
41 struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
42                                          char *system_name,
43                                          struct ntuser_creds *creds)
44 {
45         return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds);
46 }
47
48 /**********************************************************************
49  Initialize a new spoolss buff for use by a client rpc
50 **********************************************************************/
51 static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
52 {
53         buffer->ptr = (size != 0);
54         buffer->size = size;
55         buffer->string_at_end = size;
56         prs_init(&buffer->prs, size, ctx, MARSHALL);
57         buffer->struct_start = prs_offset(&buffer->prs);
58 }
59
60 /*********************************************************************
61  Decode various spoolss rpc's and info levels
62  ********************************************************************/
63
64 /**********************************************************************
65 **********************************************************************/
66 static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
67                                 uint32 returned, PRINTER_INFO_0 **info)
68 {
69         uint32 i;
70         PRINTER_INFO_0  *inf;
71
72         inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
73
74         buffer->prs.data_offset=0;
75
76         for (i=0; i<returned; i++) {
77                 smb_io_printer_info_0("", buffer, &inf[i], 0);
78         }
79
80         *info=inf;
81 }
82
83 /**********************************************************************
84 **********************************************************************/
85 static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
86                                 uint32 returned, PRINTER_INFO_1 **info)
87 {
88         uint32 i;
89         PRINTER_INFO_1  *inf;
90
91         inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
92
93         buffer->prs.data_offset=0;
94
95         for (i=0; i<returned; i++) {
96                 smb_io_printer_info_1("", buffer, &inf[i], 0);
97         }
98
99         *info=inf;
100 }
101
102 /**********************************************************************
103 **********************************************************************/
104 static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
105                                 uint32 returned, PRINTER_INFO_2 **info)
106 {
107         uint32 i;
108         PRINTER_INFO_2  *inf;
109
110         inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
111
112         buffer->prs.data_offset=0;
113
114         for (i=0; i<returned; i++) {
115                 /* a little initialization as we go */
116                 inf[i].secdesc = NULL;
117                 smb_io_printer_info_2("", buffer, &inf[i], 0);
118         }
119
120         *info=inf;
121 }
122
123 /**********************************************************************
124 **********************************************************************/
125 static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
126                                 uint32 returned, PRINTER_INFO_3 **info)
127 {
128         uint32 i;
129         PRINTER_INFO_3  *inf;
130
131         inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
132
133         buffer->prs.data_offset=0;
134
135         for (i=0; i<returned; i++) {
136                 inf[i].secdesc = NULL;
137                 smb_io_printer_info_3("", buffer, &inf[i], 0);
138         }
139
140         *info=inf;
141 }
142
143 /**********************************************************************
144 **********************************************************************/
145 static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
146                         uint32 returned, PORT_INFO_1 **info)
147 {
148         uint32 i;
149         PORT_INFO_1 *inf;
150
151         inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
152
153         prs_set_offset(&buffer->prs, 0);
154
155         for (i=0; i<returned; i++) {
156                 smb_io_port_info_1("", buffer, &(inf[i]), 0);
157         }
158
159         *info=inf;
160 }
161
162 /**********************************************************************
163 **********************************************************************/
164 static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
165                         uint32 returned, PORT_INFO_2 **info)
166 {
167         uint32 i;
168         PORT_INFO_2 *inf;
169
170         inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
171
172         prs_set_offset(&buffer->prs, 0);
173
174         for (i=0; i<returned; i++) {
175                 smb_io_port_info_2("", buffer, &(inf[i]), 0);
176         }
177
178         *info=inf;
179 }
180
181 /**********************************************************************
182 **********************************************************************/
183 static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
184                         uint32 returned, DRIVER_INFO_1 **info)
185 {
186         uint32 i;
187         DRIVER_INFO_1 *inf;
188
189         inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
190
191         buffer->prs.data_offset=0;
192
193         for (i=0; i<returned; i++) {
194                 smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
195         }
196
197         *info=inf;
198 }
199
200 /**********************************************************************
201 **********************************************************************/
202 static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
203                         uint32 returned, DRIVER_INFO_2 **info)
204 {
205         uint32 i;
206         DRIVER_INFO_2 *inf;
207
208         inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
209
210         buffer->prs.data_offset=0;
211
212         for (i=0; i<returned; i++) {
213                 smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
214         }
215
216         *info=inf;
217 }
218
219 /**********************************************************************
220 **********************************************************************/
221 static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
222                         uint32 returned, DRIVER_INFO_3 **info)
223 {
224         uint32 i;
225         DRIVER_INFO_3 *inf;
226
227         inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
228
229         buffer->prs.data_offset=0;
230
231         for (i=0; i<returned; i++) {
232                 smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
233         }
234
235         *info=inf;
236 }
237
238 /**********************************************************************
239 **********************************************************************/
240 static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
241                         uint32 returned, DRIVER_DIRECTORY_1 **info
242 )
243 {
244         DRIVER_DIRECTORY_1 *inf;
245  
246         inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
247
248         prs_set_offset(&buffer->prs, 0);
249
250         smb_io_driverdir_1("", buffer, inf, 0);
251  
252         *info=inf;
253 }
254
255 /** Return a handle to the specified printer or print server.
256  *
257  * @param cli              Pointer to client state structure which is open
258  * on the SPOOLSS pipe.
259  *
260  * @param mem_ctx          Pointer to an initialised talloc context.
261  *
262  * @param printername      The name of the printer or print server to be
263  * opened in UNC format.
264  *
265  * @param datatype         Specifies the default data type for the printer.
266  *
267  * @param access_required  The access rights requested on the printer or
268  * print server.
269  *
270  * @param station          The UNC name of the requesting workstation.
271  *
272  * @param username         The name of the user requesting the open.
273  *
274  * @param pol              Returned policy handle.
275  */
276
277 /*********************************************************************************
278  Win32 API - OpenPrinter()
279  ********************************************************************************/
280
281 WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
282                                 char *printername, char *datatype, uint32 access_required,
283                                 char *station, char *username, POLICY_HND *pol)
284 {
285         prs_struct qbuf, rbuf;
286         SPOOL_Q_OPEN_PRINTER_EX q;
287         SPOOL_R_OPEN_PRINTER_EX r;
288         WERROR result = W_ERROR(ERRgeneral);
289
290         ZERO_STRUCT(q);
291         ZERO_STRUCT(r);
292
293         /* Initialise parse structures */
294
295         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
296         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
297
298         /* Initialise input parameters */
299
300         make_spoolss_q_open_printer_ex(&q, printername, datatype,
301                                        access_required, station, username);
302
303         /* Marshall data and send request */
304
305         if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
306             !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
307                 goto done;
308
309         /* Unmarshall response */
310
311         if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0))
312                 goto done;
313
314         /* Return output parameters */
315
316         result = r.status;
317
318         if (W_ERROR_IS_OK(result))
319                 *pol = r.handle;
320
321  done:
322         prs_mem_free(&qbuf);
323         prs_mem_free(&rbuf);
324
325         return result;
326 }
327
328 /** Close a printer handle
329  *
330  * @param cli              Pointer to client state structure which is open
331  * on the SPOOLSS pipe.
332  *
333  * @param mem_ctx          Pointer to an initialised talloc context.
334  *
335  * @param pol              Policy handle of printer or print server to close.
336  */
337 /*********************************************************************************
338  Win32 API - ClosePrinter()
339  ********************************************************************************/
340
341 WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
342                                  POLICY_HND *pol)
343 {
344         prs_struct qbuf, rbuf;
345         SPOOL_Q_CLOSEPRINTER q;
346         SPOOL_R_CLOSEPRINTER r;
347         WERROR result = W_ERROR(ERRgeneral);
348
349         ZERO_STRUCT(q);
350         ZERO_STRUCT(r);
351
352         /* Initialise parse structures */
353
354         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
355         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
356
357         /* Initialise input parameters */
358
359         make_spoolss_q_closeprinter(&q, pol);
360
361         /* Marshall data and send request */
362
363         if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
364             !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
365                 goto done;
366
367         /* Unmarshall response */
368
369         if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0))
370                 goto done;
371
372         /* Return output parameters */
373
374         result = r.status;
375
376         if (W_ERROR_IS_OK(result))
377                 *pol = r.handle;
378
379  done:
380         prs_mem_free(&qbuf);
381         prs_mem_free(&rbuf);
382
383         return result;
384 }
385
386 /** Enumerate printers on a print server.
387  *
388  * @param cli              Pointer to client state structure which is open
389  *                         on the SPOOLSS pipe.
390  * @param mem_ctx          Pointer to an initialised talloc context.
391  *
392  * @param offered          Buffer size offered in the request.
393  * @param needed           Number of bytes needed to complete the request.
394  *                         may be NULL.
395  *
396  * @param flags            Selected from PRINTER_ENUM_* flags.
397  * @param level            Request information level.
398  *
399  * @param num_printers     Pointer to number of printers returned.  May be
400  *                         NULL.
401  * @param ctr              Return structure for printer information.  May
402  *                         be NULL.
403  */
404 /*********************************************************************************
405  Win32 API - EnumPrinters()
406  ********************************************************************************/
407
408 WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
409                                  uint32 offered, uint32 *needed,
410                                  uint32 flags, uint32 level,
411                                  uint32 *num_printers, PRINTER_INFO_CTR *ctr)
412 {
413         prs_struct qbuf, rbuf;
414         SPOOL_Q_ENUMPRINTERS q;
415         SPOOL_R_ENUMPRINTERS r;
416         NEW_BUFFER buffer;
417         WERROR result = W_ERROR(ERRgeneral);
418         fstring server;
419
420         ZERO_STRUCT(q);
421         ZERO_STRUCT(r);
422
423         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
424         strupper (server);
425         
426         /* Initialise input parameters */
427
428         init_buffer(&buffer, offered, mem_ctx);
429
430         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
431         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
432
433         make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, 
434                                     offered);
435
436         /* Marshall data and send request */
437         
438         if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
439             !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
440                 goto done;
441
442         /* Unmarshall response */
443
444         if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
445                 if (needed)
446                         *needed = r.needed;
447         }
448         
449         result = r.status;
450
451         /* Return output parameters */
452
453         if (!W_ERROR_IS_OK(r.status))
454                 goto done;
455
456         if (num_printers)
457                 *num_printers = r.returned;
458
459         if (!ctr)
460                 goto done;
461
462         switch (level) {
463         case 0:
464                 decode_printer_info_0(mem_ctx, r.buffer, r.returned, 
465                                       &ctr->printers_0);
466                 break;
467         case 1:
468                 decode_printer_info_1(mem_ctx, r.buffer, r.returned, 
469                                       &ctr->printers_1);
470                 break;
471         case 2:
472                 decode_printer_info_2(mem_ctx, r.buffer, r.returned, 
473                                       &ctr->printers_2);
474                 break;
475         case 3:
476                 decode_printer_info_3(mem_ctx, r.buffer, r.returned, 
477                                       &ctr->printers_3);
478                 break;
479         }                       
480         
481  done:
482         prs_mem_free(&qbuf);
483         prs_mem_free(&rbuf);
484
485         return result;  
486 }
487
488 /*********************************************************************************
489  Win32 API - EnumPorts()
490  ********************************************************************************/
491 /** Enumerate printer ports on a print server.
492  *
493  * @param cli              Pointer to client state structure which is open
494  *                         on the SPOOLSS pipe.
495  * @param mem_ctx          Pointer to an initialised talloc context.
496  *
497  * @param offered          Buffer size offered in the request.
498  * @param needed           Number of bytes needed to complete the request.
499  *                         May be NULL.
500  *
501  * @param level            Requested information level.
502  *
503  * @param num_ports        Pointer to number of ports returned.  May be NULL.
504  * @param ctr              Pointer to structure holding port information.
505  *                         May be NULL.
506  */
507
508 WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
509                               uint32 offered, uint32 *needed,
510                               uint32 level, int *num_ports, PORT_INFO_CTR *ctr)
511 {
512         prs_struct qbuf, rbuf;
513         SPOOL_Q_ENUMPORTS q;
514         SPOOL_R_ENUMPORTS r;
515         NEW_BUFFER buffer;
516         WERROR result = W_ERROR(ERRgeneral);
517         fstring server;
518
519         ZERO_STRUCT(q);
520         ZERO_STRUCT(r);
521
522         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
523         strupper (server);
524
525         /* Initialise input parameters */
526         
527         init_buffer(&buffer, offered, mem_ctx);
528         
529         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
530         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
531         
532         make_spoolss_q_enumports(&q, server, level, &buffer, offered);
533         
534         /* Marshall data and send request */
535
536         if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
537             !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
538                 goto done;
539
540         /* Unmarshall response */
541
542         if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
543                 if (needed)
544                         *needed = r.needed;
545         }
546                 
547         result = r.status;
548
549         /* Return output parameters */
550
551         if (!W_ERROR_IS_OK(result))
552                 goto done;
553
554         if (num_ports)
555                 *num_ports = r.returned;
556
557         if (!ctr)
558                 goto done;
559         
560         switch (level) {
561         case 1:
562                 decode_port_info_1(mem_ctx, r.buffer, r.returned, 
563                                    &ctr->port.info_1);
564                 break;
565         case 2:
566                 decode_port_info_2(mem_ctx, r.buffer, r.returned, 
567                                    &ctr->port.info_2);
568                 break;
569         }                       
570
571  done:
572         prs_mem_free(&qbuf);
573         prs_mem_free(&rbuf);
574         
575         return result;  
576 }
577
578 /*********************************************************************************
579  Win32 API - GetPrinter()
580  ********************************************************************************/
581
582 WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
583                               uint32 offered, uint32 *needed,
584                               POLICY_HND *pol, uint32 level, 
585                               PRINTER_INFO_CTR *ctr)
586 {
587         prs_struct qbuf, rbuf;
588         SPOOL_Q_GETPRINTER q;
589         SPOOL_R_GETPRINTER r;
590         NEW_BUFFER buffer;
591         WERROR result = W_ERROR(ERRgeneral);
592
593         ZERO_STRUCT(q);
594         ZERO_STRUCT(r);
595
596         /* Initialise input parameters */
597
598         init_buffer(&buffer, offered, mem_ctx);
599         
600         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
601         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
602
603         make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered);
604         
605         /* Marshall data and send request */
606
607         if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
608             !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
609                 goto done;
610
611         /* Unmarshall response */
612
613         if (!spoolss_io_r_getprinter("", &r, &rbuf, 0))
614                 goto done;
615
616         if (needed)
617                 *needed = r.needed;
618         
619         /* Return output parameters */
620
621         result = r.status;
622
623         if (NT_STATUS_IS_OK(result)) {
624                 switch (level) {
625                 case 0:
626                         decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
627                         break;
628                 case 1:
629                         decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
630                         break;
631                 case 2:
632                         decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
633                         break;
634                 case 3:
635                         decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
636                         break;
637                 }                       
638         }
639         
640  done:
641         prs_mem_free(&qbuf);
642         prs_mem_free(&rbuf);
643
644         return result;  
645 }
646
647 /*********************************************************************************
648  Win32 API - SetPrinter()
649  ********************************************************************************/
650 /** Set printer info 
651  *
652  * @param cli              Pointer to client state structure which is open
653  *                         on the SPOOLSS pipe.
654  * @param mem_ctx          Pointer to an initialised talloc context.
655  *
656  * @param pol              Policy handle on printer to set info.
657  * @param level            Information level to set.
658  * @param ctr              Pointer to structure holding printer information.
659  * @param command          Specifies the action performed.  See
660  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp 
661  * for details.
662  *
663  */
664
665 WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
666                               POLICY_HND *pol, uint32 level, 
667                               PRINTER_INFO_CTR *ctr, uint32 command)
668 {
669         prs_struct qbuf, rbuf;
670         SPOOL_Q_SETPRINTER q;
671         SPOOL_R_SETPRINTER r;
672         WERROR result = W_ERROR(ERRgeneral);
673
674         ZERO_STRUCT(q);
675         ZERO_STRUCT(r);
676
677         /* Initialise input parameters */
678
679         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
680         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
681                 
682         make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
683
684         /* Marshall data and send request */
685
686         if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
687             !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
688                 goto done;
689
690         /* Unmarshall response */
691
692         if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
693                 goto done;
694         
695         result = r.status;
696
697 done:
698         prs_mem_free(&qbuf);
699         prs_mem_free(&rbuf);
700
701         return result;  
702 }
703
704 /*********************************************************************************
705  Win32 API - GetPrinterDriver()
706  ********************************************************************************/
707 /** Get installed printer drivers for a given printer
708  *
709  * @param cli              Pointer to client state structure which is open
710  * on the SPOOLSS pipe.
711  *
712  * @param mem_ctx          Pointer to an initialised talloc context.
713  *
714  * @param offered          Buffer size offered in the request.
715  * @param needed           Number of bytes needed to complete the request.
716  *                         may be NULL.
717  *
718  * @param pol              Pointer to an open policy handle for the printer
719  *                         opened with cli_spoolss_open_printer_ex().
720  * @param level            Requested information level.
721  * @param env              The print environment or archictecture.  This is
722  *                         "Windows NT x86" for NT4.
723  * @param ctr              Returned printer driver information.
724  */
725
726 WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, 
727                                     TALLOC_CTX *mem_ctx, 
728                                     uint32 offered, uint32 *needed,
729                                     POLICY_HND *pol, uint32 level, 
730                                     char *env, PRINTER_DRIVER_CTR *ctr)
731 {
732         prs_struct qbuf, rbuf;
733         SPOOL_Q_GETPRINTERDRIVER2 q;
734         SPOOL_R_GETPRINTERDRIVER2 r;
735         NEW_BUFFER buffer;
736         WERROR result = W_ERROR(ERRgeneral);
737         fstring server;
738
739         ZERO_STRUCT(q);
740         ZERO_STRUCT(r);
741
742         fstrcpy (server, cli->desthost);
743         strupper (server);
744
745         /* Initialise input parameters */
746
747         init_buffer(&buffer, offered, mem_ctx);
748
749         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
750         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
751
752         make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2,
753                                          &buffer, offered);
754
755         /* Marshall data and send request */
756
757         if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
758             !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) 
759                 goto done;
760
761         /* Unmarshall response */
762
763         if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) {
764                 if (needed)
765                         *needed = r.needed;
766         }
767
768         result = r.status;
769
770         /* Return output parameters */
771
772         if (!W_ERROR_IS_OK(result))
773                 goto done;
774
775         if (!ctr)
776                 goto done;
777
778         switch (level) {
779         case 1:
780                 decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
781                 break;
782         case 2:
783                 decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
784                 break;
785         case 3:
786                 decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
787                 break;
788         }
789
790  done:
791         prs_mem_free(&qbuf);
792         prs_mem_free(&rbuf);
793                 
794         return result;  
795 }
796
797 /*********************************************************************************
798  Win32 API - EnumPrinterDrivers()
799  ********************************************************************************/
800 /**********************************************************************
801  * Get installed printer drivers for a given printer
802  */
803 WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, 
804                                        TALLOC_CTX *mem_ctx,
805                                        uint32 offered, uint32 *needed,
806                                        uint32 level, char *env,
807                                        uint32 *num_drivers,
808                                        PRINTER_DRIVER_CTR *ctr)
809 {
810         prs_struct qbuf, rbuf;
811         SPOOL_Q_ENUMPRINTERDRIVERS q;
812         SPOOL_R_ENUMPRINTERDRIVERS r;
813         NEW_BUFFER buffer;
814         WERROR result = W_ERROR(ERRgeneral);
815         fstring server;
816
817         ZERO_STRUCT(q);
818         ZERO_STRUCT(r);
819
820         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
821         strupper (server);
822
823         /* Initialise input parameters */
824
825         init_buffer(&buffer, offered, mem_ctx);
826
827         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
828         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
829
830         /* Write the request */
831
832         make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, 
833                                           offered);
834         
835         /* Marshall data and send request */
836         
837         if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
838             !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
839                 goto done;
840
841         /* Unmarshall response */
842
843         if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
844                 goto done;
845
846         if (needed)
847                 *needed = r.needed;
848
849         if (num_drivers)
850                 *num_drivers = r.returned;
851
852         result = r.status;
853
854         /* Return output parameters */
855
856         if (W_ERROR_IS_OK(result) && (r.returned != 0)) {
857                 *num_drivers = r.returned;
858
859                 switch (level) {
860                 case 1:
861                         decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
862                         break;
863                 case 2:
864                         decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
865                         break;
866                 case 3:
867                         decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
868                         break;
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 (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 (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 (client);
1026         slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1027         strupper (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, char *arch,
1071                                         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 (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, char *form_name,
1247                            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, char *formname, uint32 level, 
1309                            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                 smb_io_form_1("", r.buffer, form, 0);
1351
1352  done:
1353         prs_mem_free(&qbuf);
1354         prs_mem_free(&rbuf);
1355
1356         return result;
1357 }
1358
1359 /** Delete a form on a printer.
1360  *
1361  * @param cli              Pointer to client state structure which is open
1362  *                         on the SPOOLSS pipe.
1363  * @param mem_ctx          Pointer to an initialised talloc context.
1364  *
1365  * @param handle           Policy handle opened with cli_spoolss_open_printer_ex 
1366  *                         or cli_spoolss_addprinterex.
1367  * @param form             The name of the form to delete.
1368  *
1369  */
1370
1371 WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1372                               POLICY_HND *handle, char *form_name)
1373 {
1374         prs_struct qbuf, rbuf;
1375         SPOOL_Q_DELETEFORM q;
1376         SPOOL_R_DELETEFORM r;
1377         WERROR result = W_ERROR(ERRgeneral);
1378
1379         ZERO_STRUCT(q);
1380         ZERO_STRUCT(r);
1381
1382         /* Initialise parse structures */
1383
1384         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1385         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1386
1387         /* Initialise input parameters */
1388
1389         make_spoolss_q_deleteform(&q, handle, form_name);
1390         
1391         /* Marshall data and send request */
1392
1393         if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) ||
1394             !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
1395                 goto done;
1396
1397         /* Unmarshall response */
1398
1399         if (!spoolss_io_r_deleteform("", &r, &rbuf, 0))
1400                 goto done;
1401
1402         /* Return output parameters */
1403
1404         result = r.status;
1405
1406  done:
1407         prs_mem_free(&qbuf);
1408         prs_mem_free(&rbuf);
1409
1410         return result;
1411 }
1412
1413 static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
1414                            uint32 num_forms, FORM_1 **forms)
1415 {
1416         int i;
1417
1418         *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
1419         buffer->prs.data_offset = 0;
1420
1421         for (i = 0; i < num_forms; i++)
1422                 smb_io_form_1("", buffer, &((*forms)[i]), 0);
1423 }
1424
1425 /** Enumerate forms
1426  *
1427  * @param cli              Pointer to client state structure which is open
1428  *                         on the SPOOLSS pipe.
1429  * @param mem_ctx          Pointer to an initialised talloc context.
1430  *
1431  * @param offered          Buffer size offered in the request.
1432  * @param needed           Number of bytes needed to complete the request.
1433  *                         may be NULL.
1434  *                         or cli_spoolss_addprinterex.
1435  * @param level            Form info level to get - should always be 1.
1436  * @param handle           Open policy handle
1437  *
1438  */
1439
1440 WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1441                              uint32 offered, uint32 *needed,
1442                              POLICY_HND *handle, int level, uint32 *num_forms,
1443                              FORM_1 **forms)
1444 {
1445         prs_struct qbuf, rbuf;
1446         SPOOL_Q_ENUMFORMS q;
1447         SPOOL_R_ENUMFORMS r;
1448         WERROR result = W_ERROR(ERRgeneral);
1449         NEW_BUFFER buffer;
1450
1451         ZERO_STRUCT(q);
1452         ZERO_STRUCT(r);
1453
1454         /* Initialise parse structures */
1455
1456         init_buffer(&buffer, offered, mem_ctx);
1457
1458         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1459         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1460
1461         /* Initialise input parameters */
1462
1463         make_spoolss_q_enumforms(&q, handle, level, &buffer, offered);
1464
1465         /* Marshall data and send request */
1466
1467         if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) ||
1468             !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
1469                 goto done;
1470
1471         /* Unmarshall response */
1472
1473         if (!spoolss_io_r_enumforms("", &r, &rbuf, 0))
1474                 goto done;
1475
1476         /* Return output parameters */
1477
1478         result = r.status;
1479
1480         if (needed)
1481                 *needed = r.needed;
1482
1483         if (num_forms)
1484                 *num_forms = r.numofforms;
1485
1486         decode_forms_1(mem_ctx, r.buffer, *num_forms, forms);
1487
1488  done:
1489         prs_mem_free(&qbuf);
1490         prs_mem_free(&rbuf);
1491
1492         return result;
1493 }
1494
1495 static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
1496                           uint32 num_jobs, JOB_INFO_1 **jobs)
1497 {
1498         uint32 i;
1499
1500         *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1));
1501         buffer->prs.data_offset = 0;
1502
1503         for (i = 0; i < num_jobs; i++) 
1504                 smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
1505 }
1506
1507 static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
1508                           uint32 num_jobs, JOB_INFO_2 **jobs)
1509 {
1510         uint32 i;
1511
1512         *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2));
1513         buffer->prs.data_offset = 0;
1514
1515         for (i = 0; i < num_jobs; i++) 
1516                 smb_io_job_info_2("", buffer, &((*jobs)[i]), 0);
1517 }
1518
1519 /* Enumerate jobs */
1520
1521 WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1522                             uint32 offered, uint32 *needed,
1523                             POLICY_HND *hnd, uint32 level, uint32 firstjob, 
1524                             uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
1525 {
1526         prs_struct qbuf, rbuf;
1527         SPOOL_Q_ENUMJOBS q;
1528         SPOOL_R_ENUMJOBS r;
1529         WERROR result = W_ERROR(ERRgeneral);
1530         NEW_BUFFER buffer;
1531
1532         ZERO_STRUCT(q);
1533         ZERO_STRUCT(r);
1534
1535         /* Initialise parse structures */
1536
1537         init_buffer(&buffer, offered, mem_ctx);
1538
1539         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1540         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1541
1542         /* Initialise input parameters */
1543
1544         make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, 
1545                                 offered);
1546
1547         /* Marshall data and send request */
1548
1549         if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) ||
1550             !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf))
1551                 goto done;
1552
1553         /* Unmarshall response */
1554
1555         if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0))
1556                 goto done;
1557
1558         /* Return output parameters */
1559
1560         result = r.status;
1561
1562         if (needed)
1563                 *needed = r.needed;
1564
1565         if (!W_ERROR_IS_OK(r.status))
1566                 goto done;
1567
1568         *returned = r.returned;
1569
1570         switch(level) {
1571         case 1:
1572                 decode_jobs_1(mem_ctx, r.buffer, r.returned,
1573                               &ctr->job.job_info_1);
1574                 break;
1575         case 2:
1576                 decode_jobs_2(mem_ctx, r.buffer, r.returned,
1577                               &ctr->job.job_info_2);
1578                 break;
1579         default:
1580                 DEBUG(3, ("unsupported info level %d", level));
1581                 break;
1582         }
1583
1584  done:
1585         prs_mem_free(&qbuf);
1586         prs_mem_free(&rbuf);
1587
1588         return result;
1589 }
1590
1591 /* Set job */
1592
1593 WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1594                           POLICY_HND *hnd, uint32 jobid, uint32 level, 
1595                           uint32 command)
1596 {
1597         prs_struct qbuf, rbuf;
1598         SPOOL_Q_SETJOB q;
1599         SPOOL_R_SETJOB r;
1600         WERROR result = W_ERROR(ERRgeneral);
1601
1602         ZERO_STRUCT(q);
1603         ZERO_STRUCT(r);
1604
1605         /* Initialise parse structures */
1606
1607         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1608         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1609
1610         /* Initialise input parameters */
1611
1612         make_spoolss_q_setjob(&q, hnd, jobid, level, command);
1613
1614         /* Marshall data and send request */
1615
1616         if (!spoolss_io_q_setjob("", &q, &qbuf, 0) ||
1617             !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf))
1618                 goto done;
1619
1620         /* Unmarshall response */
1621
1622         if (!spoolss_io_r_setjob("", &r, &rbuf, 0))
1623                 goto done;
1624
1625         /* Return output parameters */
1626
1627         result = r.status;
1628
1629  done:
1630         prs_mem_free(&qbuf);
1631         prs_mem_free(&rbuf);
1632
1633         return result;
1634 }
1635
1636 /* Get job */
1637
1638 WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1639                           uint32 offered, uint32 *needed,
1640                           POLICY_HND *hnd, uint32 jobid, uint32 level,
1641                           JOB_INFO_CTR *ctr)
1642 {
1643         prs_struct qbuf, rbuf;
1644         SPOOL_Q_GETJOB q;
1645         SPOOL_R_GETJOB r;
1646         WERROR result = W_ERROR(ERRgeneral);
1647         NEW_BUFFER buffer;
1648
1649         ZERO_STRUCT(q);
1650         ZERO_STRUCT(r);
1651
1652         /* Initialise parse structures */
1653
1654         init_buffer(&buffer, offered, mem_ctx);
1655
1656         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1657         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1658
1659         /* Initialise input parameters */
1660
1661         make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered);
1662
1663         /* Marshall data and send request */
1664
1665         if (!spoolss_io_q_getjob("", &q, &qbuf, 0) ||
1666             !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf))
1667                 goto done;
1668
1669         /* Unmarshall response */
1670
1671         if (!spoolss_io_r_getjob("", &r, &rbuf, 0))
1672                 goto done;
1673
1674         /* Return output parameters */
1675
1676         result = r.status;
1677
1678         if (needed)
1679                 *needed = r.needed;
1680
1681         if (!W_ERROR_IS_OK(r.status))
1682                 goto done;
1683
1684         switch(level) {
1685         case 1:
1686                 decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1);
1687                 break;
1688         case 2:
1689                 decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2);
1690                 break;
1691         default:
1692                 DEBUG(3, ("unsupported info level %d", level));
1693                 break;
1694         }
1695
1696  done:
1697         prs_mem_free(&qbuf);
1698         prs_mem_free(&rbuf);
1699
1700         return result;
1701 }
1702
1703 /* Startpageprinter.  Sent to notify the spooler when a page is about to be
1704    sent to a printer. */ 
1705
1706 WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1707                                     POLICY_HND *hnd)
1708 {
1709         prs_struct qbuf, rbuf;
1710         SPOOL_Q_STARTPAGEPRINTER q;
1711         SPOOL_R_STARTPAGEPRINTER r;
1712         WERROR result = W_ERROR(ERRgeneral);
1713
1714         ZERO_STRUCT(q);
1715         ZERO_STRUCT(r);
1716
1717         /* Initialise parse structures */
1718
1719         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1720         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1721
1722         /* Initialise input parameters */
1723
1724         make_spoolss_q_startpageprinter(&q, hnd);
1725
1726         /* Marshall data and send request */
1727
1728         if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) ||
1729             !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf))
1730                 goto done;
1731
1732         /* Unmarshall response */
1733
1734         if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0))
1735                 goto done;
1736
1737         /* Return output parameters */
1738
1739         result = r.status;
1740
1741  done:
1742         prs_mem_free(&qbuf);
1743         prs_mem_free(&rbuf);
1744
1745         return result;
1746 }
1747
1748 /* Endpageprinter.  Sent to notify the spooler when a page has finished
1749    being sent to a printer. */
1750
1751 WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1752                                   POLICY_HND *hnd)
1753 {
1754         prs_struct qbuf, rbuf;
1755         SPOOL_Q_ENDPAGEPRINTER q;
1756         SPOOL_R_ENDPAGEPRINTER r;
1757         WERROR result = W_ERROR(ERRgeneral);
1758
1759         ZERO_STRUCT(q);
1760         ZERO_STRUCT(r);
1761
1762         /* Initialise parse structures */
1763
1764         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1765         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1766
1767         /* Initialise input parameters */
1768
1769         make_spoolss_q_endpageprinter(&q, hnd);
1770
1771         /* Marshall data and send request */
1772
1773         if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) ||
1774             !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf))
1775                 goto done;
1776
1777         /* Unmarshall response */
1778
1779         if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0))
1780                 goto done;
1781
1782         /* Return output parameters */
1783
1784         result = r.status;
1785
1786  done:
1787         prs_mem_free(&qbuf);
1788         prs_mem_free(&rbuf);
1789
1790         return result;
1791 }
1792
1793 /* Startdocprinter.  Sent to notify the spooler that a document is about
1794    to be spooled for printing. */
1795
1796 WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1797                                    POLICY_HND *hnd, char *docname, 
1798                                    char *outputfile, char *datatype, 
1799                                    uint32 *jobid)
1800 {
1801         prs_struct qbuf, rbuf;
1802         SPOOL_Q_STARTDOCPRINTER q;
1803         SPOOL_R_STARTDOCPRINTER r;
1804         WERROR result = W_ERROR(ERRgeneral);
1805         uint32 level = 1;
1806
1807         ZERO_STRUCT(q);
1808         ZERO_STRUCT(r);
1809
1810         /* Initialise parse structures */
1811
1812         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1813         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1814
1815         /* Initialise input parameters */
1816
1817         make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, 
1818                                        datatype);
1819
1820         /* Marshall data and send request */
1821
1822         if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) ||
1823             !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf))
1824                 goto done;
1825
1826         /* Unmarshall response */
1827
1828         if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0))
1829                 goto done;
1830
1831         /* Return output parameters */
1832
1833         result = r.status;
1834         
1835         if (W_ERROR_IS_OK(result))
1836                 *jobid = r.jobid;
1837
1838  done:
1839         prs_mem_free(&qbuf);
1840         prs_mem_free(&rbuf);
1841
1842         return result;
1843 }
1844
1845 /* Enddocprinter.  Sent to notify the spooler that a document has finished
1846    being spooled. */
1847
1848 WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1849                                   POLICY_HND *hnd)
1850 {
1851         prs_struct qbuf, rbuf;
1852         SPOOL_Q_ENDDOCPRINTER q;
1853         SPOOL_R_ENDDOCPRINTER r;
1854         WERROR result = W_ERROR(ERRgeneral);
1855
1856         ZERO_STRUCT(q);
1857         ZERO_STRUCT(r);
1858
1859         /* Initialise parse structures */
1860
1861         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1862         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1863
1864         /* Initialise input parameters */
1865
1866         make_spoolss_q_enddocprinter(&q, hnd);
1867
1868         /* Marshall data and send request */
1869
1870         if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) ||
1871             !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf))
1872                 goto done;
1873
1874         /* Unmarshall response */
1875
1876         if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0))
1877                 goto done;
1878
1879         /* Return output parameters */
1880
1881         result = r.status;
1882
1883  done:
1884         prs_mem_free(&qbuf);
1885         prs_mem_free(&rbuf);
1886
1887         return result;
1888 }
1889
1890 /* Get printer data */
1891
1892 WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1893                                   uint32 offered, uint32 *needed,
1894                                   POLICY_HND *hnd, char *valuename, 
1895                                   uint32 *data_type, char **data, 
1896                                   uint32 *data_size)
1897 {
1898         prs_struct qbuf, rbuf;
1899         SPOOL_Q_GETPRINTERDATA q;
1900         SPOOL_R_GETPRINTERDATA r;
1901         WERROR result = W_ERROR(ERRgeneral);
1902
1903         ZERO_STRUCT(q);
1904         ZERO_STRUCT(r);
1905
1906         /* Initialise parse structures */
1907
1908         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1909         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1910
1911         /* Initialise input parameters */
1912
1913         make_spoolss_q_getprinterdata(&q, hnd, valuename, offered);
1914
1915         /* Marshall data and send request */
1916
1917         if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) ||
1918             !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
1919                 goto done;
1920
1921         /* Unmarshall response */
1922
1923         if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0))
1924                 goto done;
1925         
1926         result = r.status;
1927
1928         if (needed)
1929                 *needed = r.needed;
1930
1931         if (!W_ERROR_IS_OK(r.status))
1932                 goto done;      
1933
1934         /* Return output parameters */
1935
1936         if (data_type)
1937                 *data_type = r.type;
1938
1939         if (data) {
1940                 *data = (char *)talloc(mem_ctx, r.needed);
1941                 memcpy(*data, r.data, r.needed);
1942         }
1943
1944         if (data_size) 
1945                 *data_size = r.needed;
1946
1947  done:
1948         prs_mem_free(&qbuf);
1949         prs_mem_free(&rbuf);
1950
1951         return result;
1952 }
1953
1954 /* Set printer data */
1955
1956 WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1957                                   POLICY_HND *hnd, char *value, 
1958                                   uint32 data_type, char *data, 
1959                                   uint32 data_size)
1960 {
1961         prs_struct qbuf, rbuf;
1962         SPOOL_Q_SETPRINTERDATA q;
1963         SPOOL_R_SETPRINTERDATA r;
1964         WERROR result = W_ERROR(ERRgeneral);
1965
1966         ZERO_STRUCT(q);
1967         ZERO_STRUCT(r);
1968
1969         /* Initialise parse structures */
1970
1971         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1972         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1973
1974         /* Initialise input parameters */
1975
1976         make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size);
1977
1978         /* Marshall data and send request */
1979
1980         if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) ||
1981             !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
1982                 goto done;
1983
1984         /* Unmarshall response */
1985
1986         if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0))
1987                 goto done;
1988         
1989         result = r.status;
1990
1991         if (!W_ERROR_IS_OK(r.status))
1992                 goto done;      
1993
1994  done:
1995         prs_mem_free(&qbuf);
1996         prs_mem_free(&rbuf);
1997
1998         return result;
1999 }
2000
2001 /* Enum printer data */
2002
2003 WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2004                                    POLICY_HND *hnd, uint32 ndx,
2005                                    uint32 value_offered, uint32 data_offered,
2006                                    uint32 *value_needed, uint32 *data_needed,
2007                                    char **value, uint32 *data_type, char **data, 
2008                                    uint32 *data_size)
2009 {
2010         prs_struct qbuf, rbuf;
2011         SPOOL_Q_ENUMPRINTERDATA q;
2012         SPOOL_R_ENUMPRINTERDATA r;
2013         WERROR result = W_ERROR(ERRgeneral);
2014
2015         ZERO_STRUCT(q);
2016         ZERO_STRUCT(r);
2017
2018         /* Initialise parse structures */
2019
2020         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2021         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2022
2023         /* Initialise input parameters */
2024
2025         make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered);
2026
2027         /* Marshall data and send request */
2028
2029         if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) ||
2030             !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf))
2031                 goto done;
2032
2033         /* Unmarshall response */
2034
2035         if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0))
2036                 goto done;
2037         
2038         result = r.status;
2039
2040         if (!W_ERROR_IS_OK(r.status))
2041                 goto done;
2042
2043         /* Return data */
2044
2045         if (value_needed)
2046                 *value_needed = r.realvaluesize;
2047
2048         if (data_needed)
2049                 *data_needed = r.realdatasize;
2050
2051         if (data_type) 
2052                 *data_type = r.type;
2053
2054         if (value) {
2055                 fstring the_value;
2056
2057                 rpcstr_pull(the_value, r.value, sizeof(the_value), -1, 
2058                             STR_TERMINATE);
2059                 
2060                 *value = talloc_strdup(mem_ctx, the_value);
2061         }
2062
2063         if (data)
2064                 *data = talloc_memdup(mem_ctx, r.data, r.realdatasize);
2065
2066         if (data_size)
2067                 *data_size = r.realdatasize;
2068
2069  done:
2070         prs_mem_free(&qbuf);
2071         prs_mem_free(&rbuf);
2072
2073         return result;
2074 }
2075
2076 /* Write data to printer */
2077
2078 WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2079                                 POLICY_HND *hnd, uint32 data_size, char *data,
2080                                 uint32 *num_written)
2081 {
2082         prs_struct qbuf, rbuf;
2083         SPOOL_Q_WRITEPRINTER q;
2084         SPOOL_R_WRITEPRINTER r;
2085         WERROR result = W_ERROR(ERRgeneral);
2086
2087         ZERO_STRUCT(q);
2088         ZERO_STRUCT(r);
2089
2090         /* Initialise parse structures */
2091
2092         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2093         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2094
2095         /* Initialise input parameters */
2096
2097         make_spoolss_q_writeprinter(&q, hnd, data_size, data);
2098
2099         /* Marshall data and send request */
2100
2101         if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
2102             !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
2103                 goto done;
2104
2105         /* Unmarshall response */
2106
2107         if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0))
2108                 goto done;
2109         
2110         result = r.status;
2111
2112         if (!W_ERROR_IS_OK(r.status))
2113                 goto done;      
2114
2115         if (num_written)
2116                 *num_written = r.buffer_written;
2117
2118  done:
2119         prs_mem_free(&qbuf);
2120         prs_mem_free(&rbuf);
2121
2122         return result;
2123 }
2124
2125 /* Delete printer data */
2126
2127 WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2128                                      POLICY_HND *hnd, char *valuename)
2129 {
2130         prs_struct qbuf, rbuf;
2131         SPOOL_Q_DELETEPRINTERDATA q;
2132         SPOOL_R_DELETEPRINTERDATA r;
2133         WERROR result = W_ERROR(ERRgeneral);
2134
2135         ZERO_STRUCT(q);
2136         ZERO_STRUCT(r);
2137
2138         /* Initialise parse structures */
2139
2140         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2141         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2142
2143         /* Initialise input parameters */
2144
2145         make_spoolss_q_deleteprinterdata(&q, hnd, valuename);
2146
2147         /* Marshall data and send request */
2148
2149         if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) ||
2150             !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf))
2151                 goto done;
2152
2153         /* Unmarshall response */
2154
2155         if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0))
2156                 goto done;
2157         
2158         result = r.status;
2159
2160         if (!W_ERROR_IS_OK(r.status))
2161                 goto done;      
2162
2163  done:
2164         prs_mem_free(&qbuf);
2165         prs_mem_free(&rbuf);
2166
2167         return result;
2168 }
2169
2170 /** @} **/