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