69cee6c8e8459a8574d834c0bf2ef40e8b2d85c3
[kai/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-2005,
6    Copyright (C) Tim Potter                   2000-2002,
7    Copyright (C) Andrew Tridgell              1994-2000,
8    Copyright (C) Jean-Francois Micouleau      1999-2000.
9    Copyright (C) Jeremy Allison                         2005.
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 3 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, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "rpc_client.h"
27
28 /*********************************************************************
29  Decode various spoolss rpc's and info levels
30  ********************************************************************/
31
32 /**********************************************************************
33 **********************************************************************/
34
35 static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
36                                 uint32 returned, PRINTER_INFO_0 **info)
37 {
38         uint32 i;
39         PRINTER_INFO_0  *inf;
40
41         if (returned) {
42                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned);
43                 if (!inf) {
44                         return False;
45                 }
46                 memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
47         } else {
48                 inf = NULL;
49         }
50
51         prs_set_offset(&buffer->prs,0);
52
53         for (i=0; i<returned; i++) {
54                 if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) {
55                         return False;
56                 }
57         }
58
59         *info=inf;
60         return True;
61 }
62
63 /**********************************************************************
64 **********************************************************************/
65
66 static bool decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
67                                 uint32 returned, PRINTER_INFO_1 **info)
68 {
69         uint32 i;
70         PRINTER_INFO_1  *inf;
71
72         if (returned) {
73                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned);
74                 if (!inf) {
75                         return False;
76                 }
77                 memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
78         } else {
79                 inf = NULL;
80         }
81
82         prs_set_offset(&buffer->prs,0);
83
84         for (i=0; i<returned; i++) {
85                 if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) {
86                         return False;
87                 }
88         }
89
90         *info=inf;
91         return True;
92 }
93
94 /**********************************************************************
95 **********************************************************************/
96
97 static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
98                                 uint32 returned, PRINTER_INFO_2 **info)
99 {
100         uint32 i;
101         PRINTER_INFO_2  *inf;
102
103         if (returned) {
104                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned);
105                 if (!inf) {
106                         return False;
107                 }
108                 memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
109         } else {
110                 inf = NULL;
111         }
112
113         prs_set_offset(&buffer->prs,0);
114
115         for (i=0; i<returned; i++) {
116                 /* a little initialization as we go */
117                 inf[i].secdesc = NULL;
118                 if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) {
119                         return False;
120                 }
121         }
122
123         *info=inf;
124         return True;
125 }
126
127 /**********************************************************************
128 **********************************************************************/
129
130 static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
131                                 uint32 returned, PRINTER_INFO_3 **info)
132 {
133         uint32 i;
134         PRINTER_INFO_3  *inf;
135
136         if (returned) {
137                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned);
138                 if (!inf) {
139                         return False;
140                 }
141                 memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
142         } else {
143                 inf = NULL;
144         }
145
146         prs_set_offset(&buffer->prs,0);
147
148         for (i=0; i<returned; i++) {
149                 inf[i].secdesc = NULL;
150                 if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) {
151                         return False;
152                 }
153         }
154
155         *info=inf;
156         return True;
157 }
158
159 /**********************************************************************
160 **********************************************************************/
161
162 static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
163                                 uint32 returned, PRINTER_INFO_7 **info)
164 {
165         uint32 i;
166         PRINTER_INFO_7  *inf;
167
168         if (returned) {
169                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned);
170                 if (!inf) {
171                         return False;
172                 }
173                 memset(inf, 0, returned*sizeof(PRINTER_INFO_7));
174         } else {
175                 inf = NULL;
176         }
177
178         prs_set_offset(&buffer->prs,0);
179
180         for (i=0; i<returned; i++) {
181                 if (!smb_io_printer_info_7("", buffer, &inf[i], 0)) {
182                         return False;
183                 }
184         }
185
186         *info=inf;
187         return True;
188 }
189
190
191 /**********************************************************************
192 **********************************************************************/
193
194 static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
195                         uint32 returned, PORT_INFO_1 **info)
196 {
197         uint32 i;
198         PORT_INFO_1 *inf;
199
200         if (returned) {
201                 inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned);
202                 if (!inf) {
203                         return False;
204                 }
205                 memset(inf, 0, returned*sizeof(PORT_INFO_1));
206         } else {
207                 inf = NULL;
208         }
209
210         prs_set_offset(&buffer->prs, 0);
211
212         for (i=0; i<returned; i++) {
213                 if (!smb_io_port_info_1("", buffer, &(inf[i]), 0)) {
214                         return False;
215                 }
216         }
217
218         *info=inf;
219         return True;
220 }
221
222 /**********************************************************************
223 **********************************************************************/
224
225 static bool decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
226                         uint32 returned, PORT_INFO_2 **info)
227 {
228         uint32 i;
229         PORT_INFO_2 *inf;
230
231         if (returned) {
232                 inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned);
233                 if (!inf) {
234                         return False;
235                 }
236                 memset(inf, 0, returned*sizeof(PORT_INFO_2));
237         } else {
238                 inf = NULL;
239         }
240
241         prs_set_offset(&buffer->prs, 0);
242
243         for (i=0; i<returned; i++) {
244                 if (!smb_io_port_info_2("", buffer, &(inf[i]), 0)) {
245                         return False;
246                 }
247         }
248
249         *info=inf;
250         return True;
251 }
252
253 /**********************************************************************
254 **********************************************************************/
255
256 static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
257                         uint32 returned, DRIVER_INFO_1 **info)
258 {
259         uint32 i;
260         DRIVER_INFO_1 *inf;
261
262         if (returned) {
263                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned);
264                 if (!inf) {
265                         return False;
266                 }
267                 memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
268         } else {
269                 inf = NULL;
270         }
271
272         prs_set_offset(&buffer->prs,0);
273
274         for (i=0; i<returned; i++) {
275                 if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) {
276                         return False;
277                 }
278         }
279
280         *info=inf;
281         return True;
282 }
283
284 /**********************************************************************
285 **********************************************************************/
286
287 static bool decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
288                         uint32 returned, DRIVER_INFO_2 **info)
289 {
290         uint32 i;
291         DRIVER_INFO_2 *inf;
292
293         if (returned) {
294                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned);
295                 if (!inf) {
296                         return False;
297                 }
298                 memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
299         } else {
300                 inf = NULL;
301         }
302
303         prs_set_offset(&buffer->prs,0);
304
305         for (i=0; i<returned; i++) {
306                 if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) {
307                         return False;
308                 }
309         }
310
311         *info=inf;
312         return True;
313 }
314
315 /**********************************************************************
316 **********************************************************************/
317
318 static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
319                         uint32 returned, DRIVER_INFO_3 **info)
320 {
321         uint32 i;
322         DRIVER_INFO_3 *inf;
323
324         if (returned) {
325                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned);
326                 if (!inf) {
327                         return False;
328                 }
329                 memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
330         } else {
331                 inf = NULL;
332         }
333
334         prs_set_offset(&buffer->prs,0);
335
336         for (i=0; i<returned; i++) {
337                 if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) {
338                         return False;
339                 }
340         }
341
342         *info=inf;
343         return True;
344 }
345
346 /**********************************************************************
347 **********************************************************************/
348
349 static bool decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
350                         uint32 returned, DRIVER_DIRECTORY_1 **info
351 )
352 {
353         DRIVER_DIRECTORY_1 *inf;
354  
355         inf=TALLOC_P(mem_ctx, DRIVER_DIRECTORY_1);
356         if (!inf) {
357                 return False;
358         }
359         memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
360
361         prs_set_offset(&buffer->prs, 0);
362
363         if (!smb_io_driverdir_1("", buffer, inf, 0)) {
364                 return False;
365         }
366  
367         *info=inf;
368         return True;
369 }
370
371 /**********************************************************************
372 **********************************************************************/
373
374 static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
375                           uint32 num_jobs, JOB_INFO_1 **jobs)
376 {
377         uint32 i;
378
379         if (num_jobs) {
380                 *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs);
381                 if (*jobs == NULL) {
382                         return False;
383                 }
384         } else {
385                 *jobs = NULL;
386         }
387         prs_set_offset(&buffer->prs,0);
388
389         for (i = 0; i < num_jobs; i++) {
390                 if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) {
391                         return False;
392                 }
393         }
394
395         return True;
396 }
397
398 /**********************************************************************
399 **********************************************************************/
400
401 static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
402                           uint32 num_jobs, JOB_INFO_2 **jobs)
403 {
404         uint32 i;
405
406         if (num_jobs) {
407                 *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs);
408                 if (*jobs == NULL) {
409                         return False;
410                 }
411         } else {
412                 *jobs = NULL;
413         }
414         prs_set_offset(&buffer->prs,0);
415
416         for (i = 0; i < num_jobs; i++) {
417                 if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) {
418                         return False;
419                 }
420         }
421
422         return True;
423 }
424
425 /**********************************************************************
426 **********************************************************************/
427
428 static bool decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
429                            uint32 num_forms, FORM_1 **forms)
430 {
431         int i;
432
433         if (num_forms) {
434                 *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms);
435                 if (*forms == NULL) {
436                         return False;
437                 }
438         } else {
439                 *forms = NULL;
440         }
441
442         prs_set_offset(&buffer->prs,0);
443
444         for (i = 0; i < num_forms; i++) {
445                 if (!smb_io_form_1("", buffer, &((*forms)[i]), 0)) {
446                         return False;
447                 }
448         }
449
450         return True;
451 }
452
453 /**********************************************************************
454 **********************************************************************/
455
456 WERROR rpccli_spoolss_open_printer_ex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
457                                 const char *printername, const char *datatype, uint32 access_required,
458                                 const char *station, const char *username, POLICY_HND *pol)
459 {
460         prs_struct qbuf, rbuf;
461         SPOOL_Q_OPEN_PRINTER_EX in;
462         SPOOL_R_OPEN_PRINTER_EX out;
463
464         ZERO_STRUCT(in);
465         ZERO_STRUCT(out);
466
467         make_spoolss_q_open_printer_ex( &in, printername, datatype,
468                 access_required, station, username );
469
470         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_OPENPRINTEREX,
471                     in, out, 
472                     qbuf, rbuf,
473                     spoolss_io_q_open_printer_ex,
474                     spoolss_io_r_open_printer_ex, 
475                     WERR_GENERAL_FAILURE );
476
477         memcpy( pol, &out.handle, sizeof(POLICY_HND) );
478         
479         return out.status;
480 }
481
482 /**********************************************************************
483 **********************************************************************/
484
485 WERROR rpccli_spoolss_close_printer(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
486                                  POLICY_HND *pol)
487 {
488         prs_struct qbuf, rbuf;
489         SPOOL_Q_CLOSEPRINTER in;
490         SPOOL_R_CLOSEPRINTER out;
491
492         ZERO_STRUCT(in);
493         ZERO_STRUCT(out);
494
495         make_spoolss_q_closeprinter( &in, pol );
496
497         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_CLOSEPRINTER,
498                     in, out, 
499                     qbuf, rbuf,
500                     spoolss_io_q_closeprinter,
501                     spoolss_io_r_closeprinter, 
502                     WERR_GENERAL_FAILURE );
503                     
504         return out.status;
505 }
506
507 /**********************************************************************
508 **********************************************************************/
509
510 WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
511                                  char *name, uint32 flags, uint32 level,
512                                  uint32 *num_printers, PRINTER_INFO_CTR *ctr)
513 {
514         prs_struct qbuf, rbuf;
515         SPOOL_Q_ENUMPRINTERS in;
516         SPOOL_R_ENUMPRINTERS out;
517         RPC_BUFFER buffer;
518         uint32 offered;
519
520         ZERO_STRUCT(in);
521         ZERO_STRUCT(out);
522
523         offered = 0;
524         rpcbuf_init(&buffer, offered, mem_ctx);
525         make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
526
527         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
528                     in, out, 
529                     qbuf, rbuf,
530                     spoolss_io_q_enumprinters,
531                     spoolss_io_r_enumprinters, 
532                     WERR_GENERAL_FAILURE );
533                     
534         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
535                 offered = out.needed;
536                 
537                 ZERO_STRUCT(in);
538                 ZERO_STRUCT(out);
539
540                 rpcbuf_init(&buffer, offered, mem_ctx);
541                 make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
542
543                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
544                             in, out, 
545                             qbuf, rbuf,
546                             spoolss_io_q_enumprinters,
547                             spoolss_io_r_enumprinters, 
548                             WERR_GENERAL_FAILURE );
549         }
550
551         if ( !W_ERROR_IS_OK(out.status) )
552                 return out.status;
553
554         switch (level) {
555         case 0:
556                 if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) {
557                         return WERR_GENERAL_FAILURE;
558                 }
559                 break;
560         case 1:
561                 if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) {
562                         return WERR_GENERAL_FAILURE;
563                 }
564                 break;
565         case 2:
566                 if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) {
567                         return WERR_GENERAL_FAILURE;
568                 }
569                 break;
570         case 3:
571                 if (!decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3)) {
572                         return WERR_GENERAL_FAILURE;
573                 }
574                 break;
575         default:
576                 return WERR_UNKNOWN_LEVEL;
577         }                       
578
579         *num_printers = out.returned;
580
581         return out.status;
582 }
583
584 /**********************************************************************
585 **********************************************************************/
586
587 WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
588                               uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
589 {
590         prs_struct qbuf, rbuf;
591         SPOOL_Q_ENUMPORTS in;
592         SPOOL_R_ENUMPORTS out;
593         RPC_BUFFER buffer;
594         fstring server;
595         uint32 offered;
596
597         ZERO_STRUCT(in);
598         ZERO_STRUCT(out);
599
600         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
601         strupper_m(server);
602
603         offered = 0;
604         rpcbuf_init(&buffer, offered, mem_ctx);
605         make_spoolss_q_enumports( &in, server, level, &buffer, offered );
606         
607         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
608                     in, out, 
609                     qbuf, rbuf,
610                     spoolss_io_q_enumports,
611                     spoolss_io_r_enumports, 
612                     WERR_GENERAL_FAILURE );
613                         
614         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
615                 offered = out.needed;
616                 
617                 ZERO_STRUCT(in);
618                 ZERO_STRUCT(out);
619                 
620                 rpcbuf_init(&buffer, offered, mem_ctx);
621                 make_spoolss_q_enumports( &in, server, level, &buffer, offered );
622
623                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
624                             in, out, 
625                             qbuf, rbuf,
626                             spoolss_io_q_enumports,
627                             spoolss_io_r_enumports, 
628                             WERR_GENERAL_FAILURE );
629         }
630         
631         if ( !W_ERROR_IS_OK(out.status) )
632                 return out.status;
633         
634         switch (level) {
635         case 1:
636                 if (!decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1)) {
637                         return WERR_GENERAL_FAILURE;
638                 }
639                 break;
640         case 2:
641                 if (!decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2)) {
642                         return WERR_GENERAL_FAILURE;
643                 }
644                 break;
645         default:
646                 return WERR_UNKNOWN_LEVEL;
647         }
648
649         *num_ports = out.returned;
650
651         return out.status;
652 }
653
654 /**********************************************************************
655 **********************************************************************/
656
657 WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
658                               POLICY_HND *pol, uint32 level, 
659                               PRINTER_INFO_CTR *ctr)
660 {
661         prs_struct qbuf, rbuf;
662         SPOOL_Q_GETPRINTER in;
663         SPOOL_R_GETPRINTER out;
664         RPC_BUFFER buffer;
665         uint32 offered;
666
667         ZERO_STRUCT(in);
668         ZERO_STRUCT(out);
669
670         /* Initialise input parameters */
671
672         offered = 0;
673         rpcbuf_init(&buffer, offered, mem_ctx);
674         make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
675         
676         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
677                     in, out, 
678                     qbuf, rbuf,
679                     spoolss_io_q_getprinter,
680                     spoolss_io_r_getprinter, 
681                     WERR_GENERAL_FAILURE );
682
683         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
684                 offered = out.needed;
685                 
686                 ZERO_STRUCT(in);
687                 ZERO_STRUCT(out);
688                 
689                 rpcbuf_init(&buffer, offered, mem_ctx);
690                 make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
691
692                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
693                             in, out, 
694                             qbuf, rbuf,
695                             spoolss_io_q_getprinter,
696                             spoolss_io_r_getprinter, 
697                             WERR_GENERAL_FAILURE );
698         }
699         
700         if ( !W_ERROR_IS_OK(out.status) )
701                 return out.status;
702                 
703         switch (level) {
704         case 0:
705                 if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) {
706                         return WERR_GENERAL_FAILURE;
707                 }
708                 break;
709         case 1:
710                 if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) {
711                         return WERR_GENERAL_FAILURE;
712                 }
713                 break;
714         case 2:
715                 if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) {
716                         return WERR_GENERAL_FAILURE;
717                 }
718                 break;
719         case 3:
720                 if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) {
721                         return WERR_GENERAL_FAILURE;
722                 }
723                 break;
724         case 7:
725                 if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) {
726                         return WERR_GENERAL_FAILURE;
727                 }
728                 break;
729         default:
730                 return WERR_UNKNOWN_LEVEL;
731         }
732
733         return out.status;
734 }
735
736 /**********************************************************************
737 **********************************************************************/
738
739 WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
740                               POLICY_HND *pol, uint32 level, 
741                               PRINTER_INFO_CTR *ctr, uint32 command)
742 {
743         prs_struct qbuf, rbuf;
744         SPOOL_Q_SETPRINTER in;
745         SPOOL_R_SETPRINTER out;
746
747         ZERO_STRUCT(in);
748         ZERO_STRUCT(out);
749
750         make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command );
751
752         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER,
753                     in, out, 
754                     qbuf, rbuf,
755                     spoolss_io_q_setprinter,
756                     spoolss_io_r_setprinter, 
757                     WERR_GENERAL_FAILURE );
758
759         return out.status;
760 }
761
762 /**********************************************************************
763 **********************************************************************/
764
765 WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, 
766                                     TALLOC_CTX *mem_ctx, 
767                                     POLICY_HND *pol, uint32 level, 
768                                     const char *env, int version, PRINTER_DRIVER_CTR *ctr)
769 {
770         prs_struct qbuf, rbuf;
771         SPOOL_Q_GETPRINTERDRIVER2 in;
772         SPOOL_R_GETPRINTERDRIVER2 out;
773         RPC_BUFFER buffer;
774         fstring server;
775         uint32 offered;
776
777         ZERO_STRUCT(in);
778         ZERO_STRUCT(out);
779
780         fstrcpy(server, cli->desthost);
781         strupper_m(server);
782
783         offered = 0;
784         rpcbuf_init(&buffer, offered, mem_ctx);
785         make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
786                 version, 2, &buffer, offered);
787
788         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
789                     in, out, 
790                     qbuf, rbuf,
791                     spoolss_io_q_getprinterdriver2,
792                     spoolss_io_r_getprinterdriver2, 
793                     WERR_GENERAL_FAILURE );
794                     
795         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
796                 offered = out.needed;
797                 
798                 ZERO_STRUCT(in);
799                 ZERO_STRUCT(out);
800                 
801                 rpcbuf_init(&buffer, offered, mem_ctx);
802                 make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
803                         version, 2, &buffer, offered);
804
805                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
806                             in, out, 
807                             qbuf, rbuf,
808                             spoolss_io_q_getprinterdriver2,
809                             spoolss_io_r_getprinterdriver2, 
810                             WERR_GENERAL_FAILURE );
811         }
812                 
813         if ( !W_ERROR_IS_OK(out.status) )
814                 return out.status;
815
816         switch (level) {
817         case 1:
818                 if (!decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
819                         return WERR_GENERAL_FAILURE;
820                 }
821                 break;
822         case 2:
823                 if (!decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2)) {
824                         return WERR_GENERAL_FAILURE;
825                 }
826                 break;
827         case 3:
828                 if (!decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3)) {
829                         return WERR_GENERAL_FAILURE;
830                 }
831                 break;
832         default:
833                 return WERR_UNKNOWN_LEVEL;
834         }
835
836         return out.status;      
837 }
838
839 /**********************************************************************
840 **********************************************************************/
841
842 WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, 
843                                        TALLOC_CTX *mem_ctx,
844                                        uint32 level, const char *env,
845                                        uint32 *num_drivers,
846                                        PRINTER_DRIVER_CTR *ctr)
847 {
848         prs_struct qbuf, rbuf;
849         SPOOL_Q_ENUMPRINTERDRIVERS in;
850         SPOOL_R_ENUMPRINTERDRIVERS out;
851         RPC_BUFFER buffer;
852         fstring server;
853         uint32 offered;
854
855         ZERO_STRUCT(in);
856         ZERO_STRUCT(out);
857
858         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
859         strupper_m(server);
860
861         offered = 0;
862         rpcbuf_init(&buffer, offered, mem_ctx);
863         make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
864                 &buffer, offered);
865         
866         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
867                     in, out, 
868                     qbuf, rbuf,
869                     spoolss_io_q_enumprinterdrivers,
870                     spoolss_io_r_enumprinterdrivers, 
871                     WERR_GENERAL_FAILURE );
872
873         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
874                 offered = out.needed;
875                 
876                 ZERO_STRUCT(in);
877                 ZERO_STRUCT(out);
878                 
879                 rpcbuf_init(&buffer, offered, mem_ctx);
880                 make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
881                         &buffer, offered);
882         
883                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
884                             in, out, 
885                             qbuf, rbuf,
886                             spoolss_io_q_enumprinterdrivers,
887                             spoolss_io_r_enumprinterdrivers, 
888                             WERR_GENERAL_FAILURE );
889         }
890         
891         *num_drivers = out.returned;
892
893         if ( !W_ERROR_IS_OK(out.status) )
894                 return out.status;
895                 
896         if ( out.returned ) {
897
898                 switch (level) {
899                 case 1:
900                         if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) {
901                                 return WERR_GENERAL_FAILURE;
902                         }
903                         break;
904                 case 2:
905                         if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) {
906                                 return WERR_GENERAL_FAILURE;
907                         }
908                         break;
909                 case 3:
910                         if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) {
911                                 return WERR_GENERAL_FAILURE;
912                         }
913                         break;
914                 default:
915                         return WERR_UNKNOWN_LEVEL;
916                 }
917         }
918
919         return out.status;
920 }
921
922
923 /**********************************************************************
924 **********************************************************************/
925
926 WERROR rpccli_spoolss_getprinterdriverdir (struct rpc_pipe_client *cli, 
927                                         TALLOC_CTX *mem_ctx,
928                                         uint32 level, char *env,
929                                         DRIVER_DIRECTORY_CTR *ctr)
930 {
931         prs_struct qbuf, rbuf;
932         SPOOL_Q_GETPRINTERDRIVERDIR in;
933         SPOOL_R_GETPRINTERDRIVERDIR out;
934         RPC_BUFFER buffer;
935         fstring server;
936         uint32 offered;
937
938         ZERO_STRUCT(in);
939         ZERO_STRUCT(out);
940
941         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
942         strupper_m(server);
943
944         offered = 0;
945         rpcbuf_init(&buffer, offered, mem_ctx);
946         make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
947                 &buffer, offered );
948
949         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
950                     in, out, 
951                     qbuf, rbuf,
952                     spoolss_io_q_getprinterdriverdir,
953                     spoolss_io_r_getprinterdriverdir, 
954                     WERR_GENERAL_FAILURE );
955                     
956         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
957                 offered = out.needed;
958                 
959                 ZERO_STRUCT(in);
960                 ZERO_STRUCT(out);
961                 
962                 rpcbuf_init(&buffer, offered, mem_ctx);
963                 make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
964                         &buffer, offered );
965
966                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
967                             in, out, 
968                             qbuf, rbuf,
969                             spoolss_io_q_getprinterdriverdir,
970                             spoolss_io_r_getprinterdriverdir, 
971                             WERR_GENERAL_FAILURE );
972         }
973         
974         if (!W_ERROR_IS_OK(out.status))
975                 return out.status;
976                 
977         if (!decode_printerdriverdir_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
978                 return WERR_GENERAL_FAILURE;
979         }
980
981         return out.status;
982 }
983
984 /**********************************************************************
985 **********************************************************************/
986
987 WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, 
988                                      TALLOC_CTX *mem_ctx, uint32 level,
989                                      PRINTER_DRIVER_CTR *ctr)
990 {
991         prs_struct qbuf, rbuf;
992         SPOOL_Q_ADDPRINTERDRIVER in;
993         SPOOL_R_ADDPRINTERDRIVER out;
994         fstring server;
995
996         ZERO_STRUCT(in);
997         ZERO_STRUCT(out);
998         
999         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1000         strupper_m(server);
1001
1002         make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr );
1003
1004         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTERDRIVER,
1005                     in, out, 
1006                     qbuf, rbuf,
1007                     spoolss_io_q_addprinterdriver,
1008                     spoolss_io_r_addprinterdriver, 
1009                     WERR_GENERAL_FAILURE );
1010
1011         return out.status;                  
1012 }
1013
1014 /**********************************************************************
1015 **********************************************************************/
1016
1017 WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1018                                  uint32 level, PRINTER_INFO_CTR*ctr)
1019 {
1020         prs_struct qbuf, rbuf;
1021         SPOOL_Q_ADDPRINTEREX in;
1022         SPOOL_R_ADDPRINTEREX out;
1023         fstring server, client, user;
1024
1025         ZERO_STRUCT(in);
1026         ZERO_STRUCT(out);
1027         
1028         slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname());
1029         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1030         
1031         strupper_m(client);
1032         strupper_m(server);
1033
1034         fstrcpy  (user, cli->auth->user_name);
1035
1036         make_spoolss_q_addprinterex( mem_ctx, &in, server, client, 
1037                 user, level, ctr);
1038
1039         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX,
1040                     in, out, 
1041                     qbuf, rbuf,
1042                     spoolss_io_q_addprinterex,
1043                     spoolss_io_r_addprinterex, 
1044                     WERR_GENERAL_FAILURE );
1045
1046         return out.status;      
1047 }
1048
1049 /**********************************************************************
1050 **********************************************************************/
1051
1052 WERROR rpccli_spoolss_deleteprinterdriverex(struct rpc_pipe_client *cli, 
1053                                          TALLOC_CTX *mem_ctx, const char *arch,
1054                                          const char *driver, int version)
1055 {
1056         prs_struct qbuf, rbuf;
1057         SPOOL_Q_DELETEPRINTERDRIVEREX in;
1058         SPOOL_R_DELETEPRINTERDRIVEREX out;
1059         fstring server;
1060
1061         ZERO_STRUCT(in);
1062         ZERO_STRUCT(out);
1063
1064         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1065         strupper_m(server);
1066
1067         make_spoolss_q_deleteprinterdriverex( mem_ctx, &in, server, arch, driver, version );
1068
1069         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDRIVEREX,
1070                     in, out, 
1071                     qbuf, rbuf,
1072                     spoolss_io_q_deleteprinterdriverex,
1073                     spoolss_io_r_deleteprinterdriverex, 
1074                     WERR_GENERAL_FAILURE );
1075                     
1076         return out.status;      
1077 }
1078
1079 /**********************************************************************
1080 **********************************************************************/
1081
1082 WERROR rpccli_spoolss_deleteprinterdriver (struct rpc_pipe_client *cli, 
1083                                         TALLOC_CTX *mem_ctx, const char *arch,
1084                                         const char *driver)
1085 {
1086         prs_struct qbuf, rbuf;
1087         SPOOL_Q_DELETEPRINTERDRIVER in;
1088         SPOOL_R_DELETEPRINTERDRIVER out;
1089         fstring server;
1090
1091         ZERO_STRUCT(in);
1092         ZERO_STRUCT(out);
1093
1094         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1095         strupper_m(server);
1096
1097         make_spoolss_q_deleteprinterdriver( mem_ctx, &in, server, arch, driver );
1098
1099         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDRIVER,
1100                     in, out, 
1101                     qbuf, rbuf,
1102                     spoolss_io_q_deleteprinterdriver,
1103                     spoolss_io_r_deleteprinterdriver, 
1104                     WERR_GENERAL_FAILURE );
1105                     
1106         return out.status;      
1107 }
1108
1109 /**********************************************************************
1110 **********************************************************************/
1111
1112 WERROR rpccli_spoolss_getprintprocessordirectory(struct rpc_pipe_client *cli,
1113                                               TALLOC_CTX *mem_ctx,
1114                                               char *name, char *environment,
1115                                               fstring procdir)
1116 {
1117         prs_struct qbuf, rbuf;
1118         SPOOL_Q_GETPRINTPROCESSORDIRECTORY in;
1119         SPOOL_R_GETPRINTPROCESSORDIRECTORY out;
1120         int level = 1;
1121         RPC_BUFFER buffer;
1122         uint32 offered;
1123
1124         ZERO_STRUCT(in);
1125         ZERO_STRUCT(out);
1126
1127         offered = 0;
1128         rpcbuf_init(&buffer, offered, mem_ctx);
1129         make_spoolss_q_getprintprocessordirectory( &in, name, 
1130                 environment, level, &buffer, offered );
1131
1132         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1133                     in, out, 
1134                     qbuf, rbuf,
1135                     spoolss_io_q_getprintprocessordirectory,
1136                     spoolss_io_r_getprintprocessordirectory, 
1137                     WERR_GENERAL_FAILURE );
1138                     
1139         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1140                 offered = out.needed;
1141                 
1142                 ZERO_STRUCT(in);
1143                 ZERO_STRUCT(out);
1144                 
1145                 rpcbuf_init(&buffer, offered, mem_ctx);
1146                 make_spoolss_q_getprintprocessordirectory( &in, name, 
1147                         environment, level, &buffer, offered );
1148
1149                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1150                             in, out, 
1151                             qbuf, rbuf,
1152                             spoolss_io_q_getprintprocessordirectory,
1153                             spoolss_io_r_getprintprocessordirectory, 
1154                             WERR_GENERAL_FAILURE );
1155         }
1156         
1157         if ( !W_ERROR_IS_OK(out.status) )
1158                 return out.status;
1159         
1160         fstrcpy(procdir, "Not implemented!");
1161         
1162         return out.status;
1163 }
1164
1165 /**********************************************************************
1166 **********************************************************************/
1167
1168 WERROR rpccli_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1169                            POLICY_HND *handle, uint32 level, FORM *form)
1170 {
1171         prs_struct qbuf, rbuf;
1172         SPOOL_Q_ADDFORM in;
1173         SPOOL_R_ADDFORM out;
1174
1175         ZERO_STRUCT(in);
1176         ZERO_STRUCT(out);
1177
1178         make_spoolss_q_addform( &in, handle, level, form );
1179         
1180         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDFORM,
1181                     in, out, 
1182                     qbuf, rbuf,
1183                     spoolss_io_q_addform,
1184                     spoolss_io_r_addform, 
1185                     WERR_GENERAL_FAILURE );
1186
1187         return out.status;
1188 }
1189
1190 /**********************************************************************
1191 **********************************************************************/
1192
1193 WERROR rpccli_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1194                            POLICY_HND *handle, uint32 level, 
1195                            const char *form_name, FORM *form)
1196 {
1197         prs_struct qbuf, rbuf;
1198         SPOOL_Q_SETFORM in;
1199         SPOOL_R_SETFORM out;
1200
1201         ZERO_STRUCT(in);
1202         ZERO_STRUCT(out);
1203
1204         make_spoolss_q_setform( &in, handle, level, form_name, form );
1205         
1206         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETFORM,
1207                     in, out, 
1208                     qbuf, rbuf,
1209                     spoolss_io_q_setform,
1210                     spoolss_io_r_setform, 
1211                     WERR_GENERAL_FAILURE );
1212
1213         return out.status;
1214 }
1215
1216 /**********************************************************************
1217 **********************************************************************/
1218
1219 WERROR rpccli_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1220                            POLICY_HND *handle, const char *formname, 
1221                            uint32 level, FORM_1 *form)
1222 {
1223         prs_struct qbuf, rbuf;
1224         SPOOL_Q_GETFORM in;
1225         SPOOL_R_GETFORM out;
1226         RPC_BUFFER buffer;
1227         uint32 offered;
1228
1229         ZERO_STRUCT(in);
1230         ZERO_STRUCT(out);
1231
1232         offered = 0;
1233         rpcbuf_init(&buffer, offered, mem_ctx);
1234         make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
1235         
1236         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETFORM,
1237                     in, out, 
1238                     qbuf, rbuf,
1239                     spoolss_io_q_getform,
1240                     spoolss_io_r_getform, 
1241                     WERR_GENERAL_FAILURE );
1242                     
1243         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1244                 offered = out.needed;
1245                 
1246                 ZERO_STRUCT(in);
1247                 ZERO_STRUCT(out);
1248                 
1249                 rpcbuf_init(&buffer, offered, mem_ctx);
1250                 make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
1251         
1252                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETFORM,
1253                             in, out, 
1254                             qbuf, rbuf,
1255                             spoolss_io_q_getform,
1256                             spoolss_io_r_getform, 
1257                             WERR_GENERAL_FAILURE );
1258         }
1259         
1260         if (!W_ERROR_IS_OK(out.status))
1261                 return out.status;
1262
1263         if (!smb_io_form_1("", out.buffer, form, 0)) {
1264                 return WERR_GENERAL_FAILURE;
1265         }
1266
1267         return out.status;
1268 }
1269
1270 /**********************************************************************
1271 **********************************************************************/
1272
1273 WERROR rpccli_spoolss_deleteform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1274                               POLICY_HND *handle, const char *form_name)
1275 {
1276         prs_struct qbuf, rbuf;
1277         SPOOL_Q_DELETEFORM in;
1278         SPOOL_R_DELETEFORM out;
1279
1280         ZERO_STRUCT(in);
1281         ZERO_STRUCT(out);
1282
1283         make_spoolss_q_deleteform( &in, handle, form_name );
1284         
1285         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEFORM,
1286                     in, out, 
1287                     qbuf, rbuf,
1288                     spoolss_io_q_deleteform,
1289                     spoolss_io_r_deleteform, 
1290                     WERR_GENERAL_FAILURE );
1291                     
1292         return out.status;
1293 }
1294
1295 /**********************************************************************
1296 **********************************************************************/
1297
1298 WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1299                              POLICY_HND *handle, int level, uint32 *num_forms,
1300                              FORM_1 **forms)
1301 {
1302         prs_struct qbuf, rbuf;
1303         SPOOL_Q_ENUMFORMS in;
1304         SPOOL_R_ENUMFORMS out;
1305         RPC_BUFFER buffer;
1306         uint32 offered;
1307
1308         ZERO_STRUCT(in);
1309         ZERO_STRUCT(out);
1310
1311         offered = 0;
1312         rpcbuf_init(&buffer, offered, mem_ctx);
1313         make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
1314
1315         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
1316                     in, out, 
1317                     qbuf, rbuf,
1318                     spoolss_io_q_enumforms,
1319                     spoolss_io_r_enumforms, 
1320                     WERR_GENERAL_FAILURE );
1321
1322         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1323                 offered = out.needed;
1324                 
1325                 ZERO_STRUCT(in);
1326                 ZERO_STRUCT(out);
1327
1328                 rpcbuf_init(&buffer, offered, mem_ctx);
1329                 make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
1330
1331                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
1332                             in, out, 
1333                             qbuf, rbuf,
1334                             spoolss_io_q_enumforms,
1335                             spoolss_io_r_enumforms, 
1336                             WERR_GENERAL_FAILURE );
1337         }
1338
1339         if (!W_ERROR_IS_OK(out.status))
1340                 return out.status;
1341
1342         *num_forms = out.numofforms;
1343         
1344         if (!decode_forms_1(mem_ctx, out.buffer, *num_forms, forms)) {
1345                 return WERR_GENERAL_FAILURE;
1346         }
1347
1348         return out.status;
1349 }
1350
1351 /**********************************************************************
1352 **********************************************************************/
1353
1354 WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1355                             POLICY_HND *hnd, uint32 level, uint32 firstjob, 
1356                             uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
1357 {
1358         prs_struct qbuf, rbuf;
1359         SPOOL_Q_ENUMJOBS in;
1360         SPOOL_R_ENUMJOBS out;
1361         RPC_BUFFER buffer;
1362         uint32 offered;
1363
1364         ZERO_STRUCT(in);
1365         ZERO_STRUCT(out);
1366
1367         offered = 0;
1368         rpcbuf_init(&buffer, offered, mem_ctx);
1369         make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
1370                 &buffer, offered );
1371
1372         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
1373                     in, out, 
1374                     qbuf, rbuf,
1375                     spoolss_io_q_enumjobs,
1376                     spoolss_io_r_enumjobs, 
1377                     WERR_GENERAL_FAILURE );
1378
1379         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1380                 offered = out.needed;
1381                 
1382                 ZERO_STRUCT(in);
1383                 ZERO_STRUCT(out);
1384
1385                 rpcbuf_init(&buffer, offered, mem_ctx);
1386                 make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
1387                         &buffer, offered );
1388
1389                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
1390                             in, out, 
1391                             qbuf, rbuf,
1392                             spoolss_io_q_enumjobs,
1393                             spoolss_io_r_enumjobs, 
1394                             WERR_GENERAL_FAILURE );
1395         }
1396
1397         if (!W_ERROR_IS_OK(out.status))
1398                 return out.status;
1399                 
1400         switch(level) {
1401         case 1:
1402                 if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) {
1403                         return WERR_GENERAL_FAILURE;
1404                 }
1405                 break;
1406         case 2:
1407                 if (!decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2)) {
1408                         return WERR_GENERAL_FAILURE;
1409                 }
1410                 break;
1411         default:
1412                 DEBUG(3, ("unsupported info level %d", level));
1413                 return WERR_UNKNOWN_LEVEL;
1414         }
1415         
1416         *returned = out.returned;
1417
1418         return out.status;
1419 }
1420
1421 /**********************************************************************
1422 **********************************************************************/
1423
1424 WERROR rpccli_spoolss_setjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1425                           POLICY_HND *hnd, uint32 jobid, uint32 level, 
1426                           uint32 command)
1427 {
1428         prs_struct qbuf, rbuf;
1429         SPOOL_Q_SETJOB in;
1430         SPOOL_R_SETJOB out;
1431
1432         ZERO_STRUCT(in);
1433         ZERO_STRUCT(out);
1434
1435         make_spoolss_q_setjob( &in, hnd, jobid, level, command );
1436
1437         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETJOB,
1438                     in, out, 
1439                     qbuf, rbuf,
1440                     spoolss_io_q_setjob,
1441                     spoolss_io_r_setjob, 
1442                     WERR_GENERAL_FAILURE );
1443                     
1444         return out.status;
1445 }
1446
1447 /**********************************************************************
1448 **********************************************************************/
1449
1450 WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1451                           POLICY_HND *hnd, uint32 jobid, uint32 level,
1452                           JOB_INFO_CTR *ctr)
1453 {
1454         prs_struct qbuf, rbuf;
1455         SPOOL_Q_GETJOB in;
1456         SPOOL_R_GETJOB out;
1457         RPC_BUFFER buffer;
1458         uint32 offered;
1459
1460         ZERO_STRUCT(in);
1461         ZERO_STRUCT(out);
1462
1463         offered = 0;
1464         rpcbuf_init(&buffer, offered, mem_ctx);
1465         make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
1466
1467         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
1468                     in, out, 
1469                     qbuf, rbuf,
1470                     spoolss_io_q_getjob,
1471                     spoolss_io_r_getjob, 
1472                     WERR_GENERAL_FAILURE );
1473
1474         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1475                 offered = out.needed;
1476                 
1477                 ZERO_STRUCT(in);
1478                 ZERO_STRUCT(out);
1479                 
1480                 rpcbuf_init(&buffer, offered, mem_ctx);
1481                 make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
1482
1483                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
1484                             in, out, 
1485                             qbuf, rbuf,
1486                             spoolss_io_q_getjob,
1487                             spoolss_io_r_getjob, 
1488                             WERR_GENERAL_FAILURE );
1489         }
1490
1491         if (!W_ERROR_IS_OK(out.status))
1492                 return out.status;
1493
1494         switch(level) {
1495         case 1:
1496                 if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) {
1497                         return WERR_GENERAL_FAILURE;
1498                 }
1499                 break;
1500         case 2:
1501                 if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) {
1502                         return WERR_GENERAL_FAILURE;
1503                 }
1504                 break;
1505         default:
1506                 return WERR_UNKNOWN_LEVEL;
1507         }
1508
1509         return out.status;
1510 }
1511
1512 /**********************************************************************
1513 **********************************************************************/
1514
1515 WERROR rpccli_spoolss_startpageprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1516                                     POLICY_HND *hnd)
1517 {
1518         prs_struct qbuf, rbuf;
1519         SPOOL_Q_STARTPAGEPRINTER in;
1520         SPOOL_R_STARTPAGEPRINTER out;
1521
1522         ZERO_STRUCT(in);
1523         ZERO_STRUCT(out);
1524
1525         make_spoolss_q_startpageprinter( &in, hnd );
1526
1527         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_STARTPAGEPRINTER,
1528                     in, out, 
1529                     qbuf, rbuf,
1530                     spoolss_io_q_startpageprinter,
1531                     spoolss_io_r_startpageprinter, 
1532                     WERR_GENERAL_FAILURE );
1533                     
1534         return out.status;
1535 }
1536
1537 /**********************************************************************
1538 **********************************************************************/
1539
1540 WERROR rpccli_spoolss_endpageprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1541                                   POLICY_HND *hnd)
1542 {
1543         prs_struct qbuf, rbuf;
1544         SPOOL_Q_ENDPAGEPRINTER in;
1545         SPOOL_R_ENDPAGEPRINTER out;
1546
1547         ZERO_STRUCT(in);
1548         ZERO_STRUCT(out);
1549
1550         make_spoolss_q_endpageprinter( &in, hnd );
1551
1552         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENDPAGEPRINTER,
1553                     in, out, 
1554                     qbuf, rbuf,
1555                     spoolss_io_q_endpageprinter,
1556                     spoolss_io_r_endpageprinter, 
1557                     WERR_GENERAL_FAILURE );
1558                     
1559         return out.status;
1560 }
1561
1562 /**********************************************************************
1563 **********************************************************************/
1564
1565 WERROR rpccli_spoolss_startdocprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1566                                    POLICY_HND *hnd, char *docname, 
1567                                    char *outputfile, char *datatype, 
1568                                    uint32 *jobid)
1569 {
1570         prs_struct qbuf, rbuf;
1571         SPOOL_Q_STARTDOCPRINTER in;
1572         SPOOL_R_STARTDOCPRINTER out;
1573         uint32 level = 1;
1574
1575         ZERO_STRUCT(in);
1576         ZERO_STRUCT(out);
1577
1578         make_spoolss_q_startdocprinter( &in, hnd, level, docname, 
1579                 outputfile, datatype );
1580
1581         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_STARTDOCPRINTER,
1582                     in, out, 
1583                     qbuf, rbuf,
1584                     spoolss_io_q_startdocprinter,
1585                     spoolss_io_r_startdocprinter, 
1586                     WERR_GENERAL_FAILURE );
1587
1588         *jobid = out.jobid;
1589
1590         return out.status;
1591 }
1592
1593 /**********************************************************************
1594 **********************************************************************/
1595
1596 WERROR rpccli_spoolss_enddocprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1597                                   POLICY_HND *hnd)
1598 {
1599         prs_struct qbuf, rbuf;
1600         SPOOL_Q_ENDDOCPRINTER in;
1601         SPOOL_R_ENDDOCPRINTER out;
1602
1603         ZERO_STRUCT(in);
1604         ZERO_STRUCT(out);
1605
1606         make_spoolss_q_enddocprinter( &in, hnd );
1607
1608         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENDDOCPRINTER,
1609                     in, out, 
1610                     qbuf, rbuf,
1611                     spoolss_io_q_enddocprinter,
1612                     spoolss_io_r_enddocprinter, 
1613                     WERR_GENERAL_FAILURE );
1614                     
1615         return out.status;
1616 }
1617
1618 /**********************************************************************
1619 **********************************************************************/
1620
1621 WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1622                                   POLICY_HND *hnd, const char *valuename, 
1623                                   REGISTRY_VALUE *value)
1624 {
1625         prs_struct qbuf, rbuf;
1626         SPOOL_Q_GETPRINTERDATA in;
1627         SPOOL_R_GETPRINTERDATA out;
1628         uint32 offered;
1629
1630         ZERO_STRUCT(in);
1631         ZERO_STRUCT(out);
1632
1633         offered = 0;
1634         make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
1635
1636         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
1637                     in, out, 
1638                     qbuf, rbuf,
1639                     spoolss_io_q_getprinterdata,
1640                     spoolss_io_r_getprinterdata, 
1641                     WERR_GENERAL_FAILURE );
1642
1643         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1644                 offered = out.needed;
1645                 
1646                 ZERO_STRUCT(in);
1647                 ZERO_STRUCT(out);
1648                 
1649                 make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
1650
1651                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
1652                             in, out, 
1653                             qbuf, rbuf,
1654                             spoolss_io_q_getprinterdata,
1655                             spoolss_io_r_getprinterdata, 
1656                             WERR_GENERAL_FAILURE );
1657         }
1658
1659         if (!W_ERROR_IS_OK(out.status))
1660                 return out.status;      
1661
1662         /* Return output parameters */
1663
1664         if (out.needed) {
1665                 value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
1666         } else {
1667                 value->data_p = NULL;
1668         }
1669         value->type = out.type;
1670         value->size = out.size;
1671
1672         return out.status;
1673 }
1674
1675 /**********************************************************************
1676 **********************************************************************/
1677
1678 WERROR rpccli_spoolss_getprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1679                                     POLICY_HND *hnd, const char *keyname, 
1680                                     const char *valuename, 
1681                                     REGISTRY_VALUE *value)
1682 {
1683         prs_struct qbuf, rbuf;
1684         SPOOL_Q_GETPRINTERDATAEX in;
1685         SPOOL_R_GETPRINTERDATAEX out;
1686         uint32 offered = 0;
1687
1688         ZERO_STRUCT(in);
1689         ZERO_STRUCT(out);
1690
1691         make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
1692
1693         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATAEX,
1694                     in, out, 
1695                     qbuf, rbuf,
1696                     spoolss_io_q_getprinterdataex,
1697                     spoolss_io_r_getprinterdataex, 
1698                     WERR_GENERAL_FAILURE );
1699
1700         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1701                 offered = out.needed;
1702                 
1703                 ZERO_STRUCT(in);
1704                 ZERO_STRUCT(out);
1705                 
1706                 make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
1707
1708                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATAEX,
1709                             in, out, 
1710                             qbuf, rbuf,
1711                             spoolss_io_q_getprinterdataex,
1712                             spoolss_io_r_getprinterdataex, 
1713                             WERR_GENERAL_FAILURE );
1714         }
1715
1716         if (!W_ERROR_IS_OK(out.status))
1717                 return out.status;      
1718
1719         /* Return output parameters */
1720
1721         if (out.needed) {
1722                 value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
1723         } else {
1724                 value->data_p = NULL;
1725         }
1726         value->type = out.type;
1727         value->size = out.needed;
1728         
1729         return out.status;
1730 }
1731
1732 /**********************************************************************
1733 **********************************************************************/
1734
1735 WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1736                                   POLICY_HND *hnd, REGISTRY_VALUE *value)
1737 {
1738         prs_struct qbuf, rbuf;
1739         SPOOL_Q_SETPRINTERDATA in;
1740         SPOOL_R_SETPRINTERDATA out;
1741
1742         ZERO_STRUCT(in);
1743         ZERO_STRUCT(out);
1744
1745         make_spoolss_q_setprinterdata( &in, hnd, value->valuename, 
1746                 value->type, (char *)value->data_p, value->size);
1747
1748         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATA,
1749                     in, out, 
1750                     qbuf, rbuf,
1751                     spoolss_io_q_setprinterdata,
1752                     spoolss_io_r_setprinterdata, 
1753                     WERR_GENERAL_FAILURE );
1754                     
1755         return out.status;
1756 }
1757
1758 /**********************************************************************
1759 **********************************************************************/
1760
1761 WERROR rpccli_spoolss_setprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1762                                     POLICY_HND *hnd, char *keyname, 
1763                                     REGISTRY_VALUE *value)
1764 {
1765         prs_struct qbuf, rbuf;
1766         SPOOL_Q_SETPRINTERDATAEX in;
1767         SPOOL_R_SETPRINTERDATAEX out;
1768         
1769         ZERO_STRUCT(in);
1770         ZERO_STRUCT(out);
1771
1772         make_spoolss_q_setprinterdataex( &in, hnd, keyname, value->valuename, 
1773                 value->type, (char *)value->data_p, value->size);
1774
1775         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATAEX,
1776                     in, out, 
1777                     qbuf, rbuf,
1778                     spoolss_io_q_setprinterdataex,
1779                     spoolss_io_r_setprinterdataex, 
1780                     WERR_GENERAL_FAILURE );
1781
1782         return out.status;
1783 }
1784
1785 /**********************************************************************
1786 **********************************************************************/
1787
1788 WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1789                                    POLICY_HND *hnd, uint32 ndx,
1790                                    uint32 value_offered, uint32 data_offered,
1791                                    uint32 *value_needed, uint32 *data_needed,
1792                                    REGISTRY_VALUE *value)
1793 {
1794         prs_struct qbuf, rbuf;
1795         SPOOL_Q_ENUMPRINTERDATA in;
1796         SPOOL_R_ENUMPRINTERDATA out;
1797
1798         ZERO_STRUCT(in);
1799         ZERO_STRUCT(out);
1800
1801         make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered );
1802
1803         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATA,
1804                     in, out, 
1805                     qbuf, rbuf,
1806                     spoolss_io_q_enumprinterdata,
1807                     spoolss_io_r_enumprinterdata, 
1808                     WERR_GENERAL_FAILURE );
1809
1810         if ( value_needed )
1811                 *value_needed = out.realvaluesize;
1812         if ( data_needed )
1813                 *data_needed = out.realdatasize;
1814                 
1815         if (!W_ERROR_IS_OK(out.status))
1816                 return out.status;
1817
1818         if (value) {
1819                 rpcstr_pull(value->valuename, out.value, sizeof(value->valuename), -1,
1820                             STR_TERMINATE);
1821                 if (out.realdatasize) {
1822                         value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data,
1823                                                        out.realdatasize);
1824                 } else {
1825                         value->data_p = NULL;
1826                 }
1827                 value->type = out.type;
1828                 value->size = out.realdatasize;
1829         }
1830         
1831         return out.status;
1832 }
1833
1834 /**********************************************************************
1835 **********************************************************************/
1836
1837 WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1838                                      POLICY_HND *hnd, const char *keyname, 
1839                                      REGVAL_CTR *ctr)
1840 {
1841         prs_struct qbuf, rbuf;
1842         SPOOL_Q_ENUMPRINTERDATAEX in;
1843         SPOOL_R_ENUMPRINTERDATAEX out;
1844         int i;
1845         uint32 offered;
1846
1847         ZERO_STRUCT(in);
1848         ZERO_STRUCT(out);
1849
1850         offered = 0;
1851         make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
1852
1853         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
1854                     in, out, 
1855                     qbuf, rbuf,
1856                     spoolss_io_q_enumprinterdataex,
1857                     spoolss_io_r_enumprinterdataex, 
1858                     WERR_GENERAL_FAILURE );
1859
1860         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1861                 offered = out.needed;
1862                 
1863                 ZERO_STRUCT(in);
1864                 ZERO_STRUCT(out);
1865                 
1866                 make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
1867
1868                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
1869                             in, out, 
1870                             qbuf, rbuf,
1871                             spoolss_io_q_enumprinterdataex,
1872                             spoolss_io_r_enumprinterdataex, 
1873                             WERR_GENERAL_FAILURE );
1874         }
1875         
1876         if (!W_ERROR_IS_OK(out.status))
1877                 return out.status;
1878
1879         for (i = 0; i < out.returned; i++) {
1880                 PRINTER_ENUM_VALUES *v = &out.ctr.values[i];
1881                 fstring name;
1882
1883                 rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, 
1884                             STR_TERMINATE);
1885                 regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
1886         }
1887
1888         return out.status;
1889 }
1890
1891 /**********************************************************************
1892 **********************************************************************/
1893
1894 WERROR rpccli_spoolss_writeprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1895                                 POLICY_HND *hnd, uint32 data_size, char *data,
1896                                 uint32 *num_written)
1897 {
1898         prs_struct qbuf, rbuf;
1899         SPOOL_Q_WRITEPRINTER in;
1900         SPOOL_R_WRITEPRINTER out;
1901
1902         ZERO_STRUCT(in);
1903         ZERO_STRUCT(out);
1904
1905         make_spoolss_q_writeprinter( &in, hnd, data_size, data );
1906
1907         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_WRITEPRINTER,
1908                     in, out, 
1909                     qbuf, rbuf,
1910                     spoolss_io_q_writeprinter,
1911                     spoolss_io_r_writeprinter, 
1912                     WERR_GENERAL_FAILURE );
1913                     
1914         if (num_written)
1915                 *num_written = out.buffer_written;
1916                 
1917         return out.status;
1918 }
1919
1920 /**********************************************************************
1921 **********************************************************************/
1922
1923 WERROR rpccli_spoolss_deleteprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1924                                      POLICY_HND *hnd, char *valuename)
1925 {
1926         prs_struct qbuf, rbuf;
1927         SPOOL_Q_DELETEPRINTERDATA in;
1928         SPOOL_R_DELETEPRINTERDATA out;
1929
1930         ZERO_STRUCT(in);
1931         ZERO_STRUCT(out);
1932
1933         make_spoolss_q_deleteprinterdata( &in, hnd, valuename );
1934
1935         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDATA,
1936                     in, out, 
1937                     qbuf, rbuf,
1938                     spoolss_io_q_deleteprinterdata,
1939                     spoolss_io_r_deleteprinterdata, 
1940                     WERR_GENERAL_FAILURE );
1941
1942         return out.status;
1943 }
1944
1945 /**********************************************************************
1946 **********************************************************************/
1947
1948 WERROR rpccli_spoolss_deleteprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1949                                        POLICY_HND *hnd, char *keyname, 
1950                                        char *valuename)
1951 {
1952         prs_struct qbuf, rbuf;
1953         SPOOL_Q_DELETEPRINTERDATAEX in;
1954         SPOOL_R_DELETEPRINTERDATAEX out;
1955
1956         ZERO_STRUCT(in);
1957         ZERO_STRUCT(out);
1958
1959         make_spoolss_q_deleteprinterdataex( &in, hnd, keyname, valuename );
1960
1961         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDATAEX,
1962                     in, out, 
1963                     qbuf, rbuf,
1964                     spoolss_io_q_deleteprinterdataex,
1965                     spoolss_io_r_deleteprinterdataex, 
1966                     WERR_GENERAL_FAILURE );
1967
1968         return out.status;
1969 }
1970
1971 /**********************************************************************
1972 **********************************************************************/
1973
1974 WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1975                                   POLICY_HND *hnd, const char *keyname,
1976                                   uint16 **keylist, uint32 *len)
1977 {
1978         prs_struct qbuf, rbuf;
1979         SPOOL_Q_ENUMPRINTERKEY in;
1980         SPOOL_R_ENUMPRINTERKEY out;
1981         uint32 offered = 0;
1982
1983         ZERO_STRUCT(in);
1984         ZERO_STRUCT(out);
1985
1986         make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
1987
1988         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
1989                     in, out, 
1990                     qbuf, rbuf,
1991                     spoolss_io_q_enumprinterkey,
1992                     spoolss_io_r_enumprinterkey, 
1993                     WERR_GENERAL_FAILURE );
1994
1995         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1996                 offered = out.needed;
1997                 
1998                 ZERO_STRUCT(in);
1999                 ZERO_STRUCT(out);
2000                 
2001                 make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
2002
2003                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
2004                             in, out, 
2005                             qbuf, rbuf,
2006                             spoolss_io_q_enumprinterkey,
2007                             spoolss_io_r_enumprinterkey, 
2008                             WERR_GENERAL_FAILURE );
2009         }
2010
2011         if ( !W_ERROR_IS_OK(out.status) )
2012                 return out.status;      
2013         
2014         if (keylist) {
2015                 *keylist = SMB_MALLOC_ARRAY(uint16, out.keys.buf_len);
2016                 if (!*keylist) {
2017                         return WERR_NOMEM;
2018                 }
2019                 memcpy(*keylist, out.keys.buffer, out.keys.buf_len * 2);
2020                 if (len)
2021                         *len = out.keys.buf_len * 2;
2022         }
2023
2024         return out.status;
2025 }
2026
2027 /**********************************************************************
2028 **********************************************************************/
2029
2030 WERROR rpccli_spoolss_deleteprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2031                                     POLICY_HND *hnd, char *keyname)
2032 {
2033         prs_struct qbuf, rbuf;
2034         SPOOL_Q_DELETEPRINTERKEY in;
2035         SPOOL_R_DELETEPRINTERKEY out;
2036
2037         ZERO_STRUCT(in);
2038         ZERO_STRUCT(out);
2039
2040         make_spoolss_q_deleteprinterkey( &in, hnd, keyname );
2041
2042         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERKEY,
2043                     in, out, 
2044                     qbuf, rbuf,
2045                     spoolss_io_q_deleteprinterkey,
2046                     spoolss_io_r_deleteprinterkey, 
2047                     WERR_GENERAL_FAILURE );
2048                     
2049         return out.status;
2050 }
2051
2052 /** @} **/