fixed memory leaks in rpcclient's cmd_spoolss_XXX() functions
[Samba.git] / source / libsmb / cli_spoolss.c
blobf68483dabe315b37a54d8827050d1a7fbebe6f7f
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.2
4 RPC pipe client
6 Copyright (C) Gerald Carter 2001,
7 Copyright (C) Tim Potter 2000,
8 Copyright (C) Andrew Tridgell 1994-2000
9 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
10 Copyright (C) Jean-Francois Micouleau 1999-2000
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "includes.h"
29 extern pstring global_myname;
31 /* Opens a SMB connection to the SPOOLSS pipe */
32 struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
33 char *system_name,
34 struct ntuser_creds *creds)
36 struct in_addr dest_ip;
37 struct nmb_name calling, called;
38 fstring dest_host;
39 extern pstring global_myname;
40 struct ntuser_creds anon;
42 /* Initialise cli_state information */
44 if (!cli_initialise(cli)) {
45 return NULL;
48 if (!creds) {
49 ZERO_STRUCT(anon);
50 anon.pwd.null_pwd = 1;
51 creds = &anon;
54 cli_init_creds(cli, creds);
56 /* Establish a SMB connection */
58 if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
59 return NULL;
62 make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
63 make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
65 if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
66 &called, "IPC$", "IPC", False, True)) {
67 return NULL;
70 /* Open a NT session thingy */
72 if (!cli_nt_session_open(cli, PIPE_SPOOLSS)) {
73 cli_shutdown(cli);
74 return NULL;
77 return cli;
80 /* Shut down a SMB connection to the SPOOLSS pipe */
82 void cli_spoolss_shutdown(struct cli_state *cli)
84 if (cli->fd != -1) cli_ulogoff(cli);
85 cli_shutdown(cli);
88 /* Open printer ex */
90 uint32 cli_spoolss_open_printer_ex(
91 struct cli_state *cli,
92 TALLOC_CTX *mem_ctx,
93 char *printername,
94 char *datatype,
95 uint32 access_required,
96 char *station,
97 char *username,
98 POLICY_HND *pol
101 prs_struct qbuf, rbuf;
102 SPOOL_Q_OPEN_PRINTER_EX q;
103 SPOOL_R_OPEN_PRINTER_EX r;
104 uint32 result;
106 ZERO_STRUCT(q);
107 ZERO_STRUCT(r);
109 /* Initialise parse structures */
111 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
112 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
114 /* Initialise input parameters */
116 make_spoolss_q_open_printer_ex(&q, printername, datatype,
117 access_required, station, username);
119 /* Marshall data and send request */
121 if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
122 !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) {
123 result = NT_STATUS_UNSUCCESSFUL;
124 goto done;
127 /* Unmarshall response */
129 if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) {
130 result = NT_STATUS_UNSUCCESSFUL;
131 goto done;
134 /* Return output parameters */
136 if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
137 *pol = r.handle;
140 done:
141 prs_mem_free(&qbuf);
142 prs_mem_free(&rbuf);
144 return result;
147 /* Close a printer handle */
149 uint32 cli_spoolss_close_printer(
150 struct cli_state *cli,
151 TALLOC_CTX *mem_ctx,
152 POLICY_HND *pol
155 prs_struct qbuf, rbuf;
156 SPOOL_Q_CLOSEPRINTER q;
157 SPOOL_R_CLOSEPRINTER r;
158 uint32 result;
160 ZERO_STRUCT(q);
161 ZERO_STRUCT(r);
163 /* Initialise parse structures */
165 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
166 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
168 /* Initialise input parameters */
170 make_spoolss_q_closeprinter(&q, pol);
172 /* Marshall data and send request */
174 if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
175 !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) {
176 result = NT_STATUS_UNSUCCESSFUL;
177 goto done;
180 /* Unmarshall response */
182 if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) {
183 result = NT_STATUS_UNSUCCESSFUL;
184 goto done;
187 /* Return output parameters */
189 if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
190 *pol = r.handle;
193 done:
194 prs_mem_free(&qbuf);
195 prs_mem_free(&rbuf);
197 return result;
200 /* Initialize a spoolss NEW_BUFFER */
202 static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
204 buffer->ptr = (size != 0);
205 buffer->size = size;
206 buffer->string_at_end = size;
207 prs_init(&buffer->prs, size, ctx, MARSHALL);
208 buffer->struct_start = prs_offset(&buffer->prs);
211 /* Decode various printer info levels - perhaps this should live in
212 parse_spoolss.c? */
214 static void decode_printer_info_0(
215 TALLOC_CTX *mem_ctx,
216 NEW_BUFFER *buffer,
217 uint32 returned,
218 PRINTER_INFO_0 **info
221 uint32 i;
222 PRINTER_INFO_0 *inf;
224 inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
226 buffer->prs.data_offset=0;
228 for (i=0; i<returned; i++) {
229 smb_io_printer_info_0("", buffer, &inf[i], 0);
232 *info=inf;
235 static void decode_printer_info_1(
236 TALLOC_CTX *mem_ctx,
237 NEW_BUFFER *buffer,
238 uint32 returned,
239 PRINTER_INFO_1 **info
242 uint32 i;
243 PRINTER_INFO_1 *inf;
245 inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
247 buffer->prs.data_offset=0;
249 for (i=0; i<returned; i++) {
250 smb_io_printer_info_1("", buffer, &inf[i], 0);
253 *info=inf;
256 static void decode_printer_info_2(
257 TALLOC_CTX *mem_ctx,
258 NEW_BUFFER *buffer,
259 uint32 returned,
260 PRINTER_INFO_2 **info
263 uint32 i;
264 PRINTER_INFO_2 *inf;
266 inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
268 buffer->prs.data_offset=0;
270 for (i=0; i<returned; i++) {
271 /* a little initialization as we go */
272 inf[i].secdesc = NULL;
273 smb_io_printer_info_2("", buffer, &inf[i], 0);
276 *info=inf;
279 static void decode_printer_info_3(
280 TALLOC_CTX *mem_ctx,
281 NEW_BUFFER *buffer,
282 uint32 returned,
283 PRINTER_INFO_3 **info
286 uint32 i;
287 PRINTER_INFO_3 *inf;
289 inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
291 buffer->prs.data_offset=0;
293 for (i=0; i<returned; i++) {
294 inf[i].secdesc = NULL;
295 smb_io_printer_info_3("", buffer, &inf[i], 0);
298 *info=inf;
301 /**********************************************************************
302 Decode a PORT_INFO_1 struct from a NEW_BUFFER
303 **********************************************************************/
304 static void decode_port_info_1(
305 TALLOC_CTX *mem_ctx,
306 NEW_BUFFER *buffer,
307 uint32 returned,
308 PORT_INFO_1 **info
311 uint32 i;
312 PORT_INFO_1 *inf;
314 inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
316 prs_set_offset(&buffer->prs, 0);
318 for (i=0; i<returned; i++) {
319 smb_io_port_info_1("", buffer, &(inf[i]), 0);
322 *info=inf;
325 /**********************************************************************
326 Decode a PORT_INFO_2 struct from a NEW_BUFFER
327 **********************************************************************/
328 static void decode_port_info_2(
329 TALLOC_CTX *mem_ctx,
330 NEW_BUFFER *buffer,
331 uint32 returned,
332 PORT_INFO_2 **info)
334 uint32 i;
335 PORT_INFO_2 *inf;
337 inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
339 prs_set_offset(&buffer->prs, 0);
341 for (i=0; i<returned; i++) {
342 smb_io_port_info_2("", buffer, &(inf[i]), 0);
345 *info=inf;
348 static void decode_printer_driver_1(
349 TALLOC_CTX *mem_ctx,
350 NEW_BUFFER *buffer,
351 uint32 returned,
352 DRIVER_INFO_1 **info
355 uint32 i;
356 DRIVER_INFO_1 *inf;
358 inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
360 buffer->prs.data_offset=0;
362 for (i=0; i<returned; i++) {
363 smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
366 *info=inf;
369 static void decode_printer_driver_2(
370 TALLOC_CTX *mem_ctx,
371 NEW_BUFFER *buffer,
372 uint32 returned,
373 DRIVER_INFO_2 **info
376 uint32 i;
377 DRIVER_INFO_2 *inf;
379 inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
381 buffer->prs.data_offset=0;
383 for (i=0; i<returned; i++) {
384 smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
387 *info=inf;
390 static void decode_printer_driver_3(
391 TALLOC_CTX *mem_ctx,
392 NEW_BUFFER *buffer,
393 uint32 returned,
394 DRIVER_INFO_3 **info
397 uint32 i;
398 DRIVER_INFO_3 *inf;
400 inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
402 buffer->prs.data_offset=0;
404 for (i=0; i<returned; i++) {
405 smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
408 *info=inf;
411 static void decode_printerdriverdir_1 (
412 TALLOC_CTX *mem_ctx,
413 NEW_BUFFER *buffer,
414 uint32 returned,
415 DRIVER_DIRECTORY_1 **info
418 DRIVER_DIRECTORY_1 *inf;
420 inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
422 prs_set_offset(&buffer->prs, 0);
424 smb_io_driverdir_1("", buffer, inf, 0);
426 *info=inf;
430 /* Enumerate printers */
432 uint32 cli_spoolss_enum_printers(
433 struct cli_state *cli,
434 TALLOC_CTX *mem_ctx,
435 uint32 flags,
436 uint32 level,
437 int *returned,
438 PRINTER_INFO_CTR *ctr
441 prs_struct qbuf, rbuf;
442 SPOOL_Q_ENUMPRINTERS q;
443 SPOOL_R_ENUMPRINTERS r;
444 NEW_BUFFER buffer;
445 uint32 needed = 100;
446 uint32 result;
447 fstring server;
449 ZERO_STRUCT(q);
450 ZERO_STRUCT(r);
452 fstrcpy (server, cli->desthost);
453 strupper (server);
455 do {
456 /* Initialise input parameters */
458 init_buffer(&buffer, needed, mem_ctx);
460 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
461 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
463 make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
464 needed);
466 /* Marshall data and send request */
468 if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
469 !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) {
470 result = NT_STATUS_UNSUCCESSFUL;
471 goto done;
474 /* Unmarshall response */
475 if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
476 needed = r.needed;
479 /* Return output parameters */
481 if (((result=r.status) == NT_STATUS_NOPROBLEMO) && (*returned = r.returned))
484 switch (level) {
485 case 1:
486 decode_printer_info_1(mem_ctx, r.buffer, r.returned,
487 &ctr->printers_1);
488 break;
489 case 2:
490 decode_printer_info_2(mem_ctx, r.buffer, r.returned,
491 &ctr->printers_2);
492 break;
493 case 3:
494 decode_printer_info_3(mem_ctx, r.buffer, r.returned,
495 &ctr->printers_3);
496 break;
500 done:
501 prs_mem_free(&qbuf);
502 prs_mem_free(&rbuf);
504 } while (result == ERROR_INSUFFICIENT_BUFFER);
506 return result;
509 /* Enumerate printer ports */
510 uint32 cli_spoolss_enum_ports(
511 struct cli_state *cli,
512 TALLOC_CTX *mem_ctx,
513 uint32 level,
514 int *returned,
515 PORT_INFO_CTR *ctr
518 prs_struct qbuf, rbuf;
519 SPOOL_Q_ENUMPORTS q;
520 SPOOL_R_ENUMPORTS r;
521 NEW_BUFFER buffer;
522 uint32 needed = 100;
523 uint32 result;
524 fstring server;
526 ZERO_STRUCT(q);
527 ZERO_STRUCT(r);
529 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
530 strupper (server);
532 do {
533 /* Initialise input parameters */
535 init_buffer(&buffer, needed, mem_ctx);
537 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
538 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
540 make_spoolss_q_enumports(&q, server, level, &buffer, needed);
542 /* Marshall data and send request */
544 if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
545 !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) {
546 result = NT_STATUS_UNSUCCESSFUL;
547 goto done;
550 /* Unmarshall response */
551 if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
552 needed = r.needed;
555 /* Return output parameters */
557 if ((result = r.status) == NT_STATUS_NOPROBLEMO &&
558 r.returned > 0) {
560 *returned = r.returned;
562 switch (level) {
563 case 1:
564 decode_port_info_1(mem_ctx, r.buffer, r.returned,
565 &ctr->port.info_1);
566 break;
567 case 2:
568 decode_port_info_2(mem_ctx, r.buffer, r.returned,
569 &ctr->port.info_2);
570 break;
574 done:
575 prs_mem_free(&qbuf);
576 prs_mem_free(&rbuf);
578 } while (result == ERROR_INSUFFICIENT_BUFFER);
580 return result;
583 /* Get printer info */
584 uint32 cli_spoolss_getprinter(
585 struct cli_state *cli,
586 TALLOC_CTX *mem_ctx,
587 POLICY_HND *pol,
588 uint32 level,
589 PRINTER_INFO_CTR *ctr
592 prs_struct qbuf, rbuf;
593 SPOOL_Q_GETPRINTER q;
594 SPOOL_R_GETPRINTER r;
595 NEW_BUFFER buffer;
596 uint32 needed = 100;
597 uint32 result;
599 ZERO_STRUCT(q);
600 ZERO_STRUCT(r);
602 do {
603 /* Initialise input parameters */
605 init_buffer(&buffer, needed, mem_ctx);
607 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
608 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
610 make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, needed);
612 /* Marshall data and send request */
613 if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
614 !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
616 result = NT_STATUS_UNSUCCESSFUL;
617 goto done;
620 /* Unmarshall response */
621 if (spoolss_io_r_getprinter("", &r, &rbuf, 0)) {
622 needed = r.needed;
625 /* Return output parameters */
626 if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
628 switch (level) {
629 case 0:
630 decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
631 break;
632 case 1:
633 decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
634 break;
635 case 2:
636 decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
637 break;
638 case 3:
639 decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
640 break;
644 done:
645 prs_mem_free(&qbuf);
646 prs_mem_free(&rbuf);
648 } while (result == ERROR_INSUFFICIENT_BUFFER);
650 return result;
653 /**********************************************************************
654 * Set printer info
656 uint32 cli_spoolss_setprinter(
657 struct cli_state *cli,
658 TALLOC_CTX *mem_ctx,
659 POLICY_HND *pol,
660 uint32 level,
661 PRINTER_INFO_CTR *ctr,
662 uint32 command
665 prs_struct qbuf, rbuf;
666 SPOOL_Q_SETPRINTER q;
667 SPOOL_R_SETPRINTER r;
668 uint32 result = NT_STATUS_UNSUCCESSFUL;
670 ZERO_STRUCT(q);
671 ZERO_STRUCT(r);
673 /* Initialise input parameters */
674 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
675 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
677 make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
679 /* Marshall data and send request */
680 result = NT_STATUS_UNSUCCESSFUL;
681 if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
682 !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
684 result = NT_STATUS_UNSUCCESSFUL;
685 goto done;
688 /* Unmarshall response */
689 result = NT_STATUS_UNSUCCESSFUL;
690 if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
692 goto done;
695 result = r.status;
697 done:
698 prs_mem_free(&qbuf);
699 prs_mem_free(&rbuf);
702 return result;
705 /**********************************************************************
706 * Get installed printer drivers for a given printer
708 uint32 cli_spoolss_getprinterdriver (
709 struct cli_state *cli,
710 TALLOC_CTX *mem_ctx,
711 POLICY_HND *pol,
712 uint32 level,
713 char* env,
714 PRINTER_DRIVER_CTR *ctr
717 prs_struct qbuf, rbuf;
718 SPOOL_Q_GETPRINTERDRIVER2 q;
719 SPOOL_R_GETPRINTERDRIVER2 r;
720 NEW_BUFFER buffer;
721 uint32 needed = 1024;
722 uint32 result;
723 fstring server;
725 ZERO_STRUCT(q);
726 ZERO_STRUCT(r);
728 fstrcpy (server, cli->desthost);
729 strupper (server);
733 /* Initialise input parameters */
735 init_buffer(&buffer, needed, mem_ctx);
737 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
738 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
741 /* write the request */
742 make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, &buffer, needed);
744 /* Marshall data and send request */
745 if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
746 !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
748 result = NT_STATUS_UNSUCCESSFUL;
749 goto done;
752 /* Unmarshall response */
753 if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0))
755 needed = r.needed;
758 /* Return output parameters */
759 if ((result = r.status) == NT_STATUS_NOPROBLEMO)
762 switch (level)
764 case 1:
765 decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
766 break;
767 case 2:
768 decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
769 break;
770 case 3:
771 decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
772 break;
776 done:
777 prs_mem_free(&qbuf);
778 prs_mem_free(&rbuf);
780 } while (result == ERROR_INSUFFICIENT_BUFFER);
782 return result;
785 /**********************************************************************
786 * Get installed printer drivers for a given printer
788 uint32 cli_spoolss_enumprinterdrivers (
789 struct cli_state *cli,
790 TALLOC_CTX *mem_ctx,
791 uint32 level,
792 char* env,
793 uint32 *returned,
794 PRINTER_DRIVER_CTR *ctr
797 prs_struct qbuf, rbuf;
798 SPOOL_Q_ENUMPRINTERDRIVERS q;
799 SPOOL_R_ENUMPRINTERDRIVERS r;
800 NEW_BUFFER buffer;
801 uint32 needed = 0;
802 uint32 result;
803 fstring server;
805 ZERO_STRUCT(q);
806 ZERO_STRUCT(r);
808 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
809 strupper (server);
813 /* Initialise input parameters */
814 init_buffer(&buffer, needed, mem_ctx);
816 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
817 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
820 /* write the request */
821 make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, needed);
823 /* Marshall data and send request */
824 if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
825 !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
827 result = NT_STATUS_UNSUCCESSFUL;
828 goto done;
831 /* Unmarshall response */
832 if (spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
834 needed = r.needed;
837 /* Return output parameters */
838 if (((result=r.status) == NT_STATUS_NOPROBLEMO) &&
839 (r.returned != 0))
841 *returned = r.returned;
843 switch (level)
845 case 1:
846 decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
847 break;
848 case 2:
849 decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
850 break;
851 case 3:
852 decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
853 break;
857 done:
858 prs_mem_free(&qbuf);
859 prs_mem_free(&rbuf);
861 } while (result == ERROR_INSUFFICIENT_BUFFER);
863 return result;
867 /**********************************************************************
868 * Get installed printer drivers for a given printer
870 uint32 cli_spoolss_getprinterdriverdir (
871 struct cli_state *cli,
872 TALLOC_CTX *mem_ctx,
873 uint32 level,
874 char* env,
875 DRIVER_DIRECTORY_CTR *ctr
878 prs_struct qbuf, rbuf;
879 SPOOL_Q_GETPRINTERDRIVERDIR q;
880 SPOOL_R_GETPRINTERDRIVERDIR r;
881 NEW_BUFFER buffer;
882 uint32 needed = 100;
883 uint32 result;
884 fstring server;
886 ZERO_STRUCT(q);
887 ZERO_STRUCT(r);
889 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
890 strupper (server);
894 /* Initialise input parameters */
895 init_buffer(&buffer, needed, mem_ctx);
897 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
898 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
901 /* write the request */
902 make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, needed);
904 /* Marshall data and send request */
905 if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
906 !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &qbuf, &rbuf))
908 result = NT_STATUS_UNSUCCESSFUL;
909 goto done;
912 /* Unmarshall response */
913 if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0))
915 needed = r.needed;
918 /* Return output parameters */
919 if ((result=r.status) == NT_STATUS_NOPROBLEMO)
921 switch (level)
923 case 1:
924 decode_printerdriverdir_1(mem_ctx, r.buffer, 1, &ctr->info1);
925 break;
929 done:
930 prs_mem_free(&qbuf);
931 prs_mem_free(&rbuf);
933 } while (result == ERROR_INSUFFICIENT_BUFFER);
935 return result;
938 /**********************************************************************
939 * Install a printer driver
941 uint32 cli_spoolss_addprinterdriver (
942 struct cli_state *cli,
943 TALLOC_CTX *mem_ctx,
944 uint32 level,
945 PRINTER_DRIVER_CTR *ctr
948 prs_struct qbuf, rbuf;
949 SPOOL_Q_ADDPRINTERDRIVER q;
950 SPOOL_R_ADDPRINTERDRIVER r;
951 uint32 result = NT_STATUS_UNSUCCESSFUL;
952 fstring server;
954 ZERO_STRUCT(q);
955 ZERO_STRUCT(r);
957 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
958 strupper (server);
960 /* Initialise input parameters */
961 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
962 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
965 /* write the request */
966 make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr);
968 /* Marshall data and send request */
969 result = NT_STATUS_UNSUCCESSFUL;
970 if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
971 !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
973 goto done;
977 /* Unmarshall response */
978 result = NT_STATUS_UNSUCCESSFUL;
979 if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
981 goto done;
984 /* Return output parameters */
985 result = r.status;
987 done:
988 prs_mem_free(&qbuf);
989 prs_mem_free(&rbuf);
991 return result;
994 /**********************************************************************
995 * Install a printer
997 uint32 cli_spoolss_addprinterex (
998 struct cli_state *cli,
999 TALLOC_CTX *mem_ctx,
1000 uint32 level,
1001 PRINTER_INFO_CTR *ctr
1004 prs_struct qbuf, rbuf;
1005 SPOOL_Q_ADDPRINTEREX q;
1006 SPOOL_R_ADDPRINTEREX r;
1007 uint32 result;
1008 fstring server,
1009 client,
1010 user;
1012 ZERO_STRUCT(q);
1013 ZERO_STRUCT(r);
1015 slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1016 strupper (client);
1017 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1018 strupper (server);
1019 fstrcpy (user, cli->user_name);
1022 /* Initialise input parameters */
1023 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1024 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1027 /* write the request */
1028 make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, level, ctr);
1030 /* Marshall data and send request */
1031 result = NT_STATUS_UNSUCCESSFUL;
1032 if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
1033 !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
1035 goto done;
1039 /* Unmarshall response */
1040 result = NT_STATUS_UNSUCCESSFUL;
1041 if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
1043 goto done;
1046 /* Return output parameters */
1047 result = r.status;
1049 done:
1050 prs_mem_free(&qbuf);
1051 prs_mem_free(&rbuf);
1053 return result;