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