few edits
[Samba.git] / source / libsmb / cli_spoolss.c
blobc56ecf05f8016393ae7f5a6729f6e988e52e075f
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
5 Copyright (C) Gerald Carter 2001-2002,
6 Copyright (C) Tim Potter 2000-2002,
7 Copyright (C) Andrew Tridgell 1994-2000,
8 Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
9 Copyright (C) Jean-Francois Micouleau 1999-2000.
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.
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.
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.
26 #include "includes.h"
28 /** @defgroup spoolss SPOOLSS - NT printing routines
29 * @ingroup rpc_client
31 * @{
32 **/
34 /** Opens a SMB connection and connects to the SPOOLSS pipe.
36 * @param cli Uninitialised client handle.
37 * @param system_name NETBIOS name of the machine to connect to.
38 * @param creds User credentials to connect as.
39 * @returns Initialised client handle.
41 struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
42 char *system_name,
43 struct ntuser_creds *creds)
45 return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds);
49 /**********************************************************************
50 Initialize a new spoolss buff for use by a client rpc
51 **********************************************************************/
52 static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
54 buffer->ptr = (size != 0);
55 buffer->size = size;
56 buffer->string_at_end = size;
57 prs_init(&buffer->prs, size, ctx, MARSHALL);
58 buffer->struct_start = prs_offset(&buffer->prs);
61 /*********************************************************************
62 Decode various spoolss rpc's and info levels
63 ********************************************************************/
65 /**********************************************************************
66 **********************************************************************/
67 static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
68 uint32 returned, PRINTER_INFO_0 **info)
70 uint32 i;
71 PRINTER_INFO_0 *inf;
73 inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
75 buffer->prs.data_offset=0;
77 for (i=0; i<returned; i++) {
78 smb_io_printer_info_0("", buffer, &inf[i], 0);
81 *info=inf;
84 /**********************************************************************
85 **********************************************************************/
86 static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
87 uint32 returned, PRINTER_INFO_1 **info)
89 uint32 i;
90 PRINTER_INFO_1 *inf;
92 inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
94 buffer->prs.data_offset=0;
96 for (i=0; i<returned; i++) {
97 smb_io_printer_info_1("", buffer, &inf[i], 0);
100 *info=inf;
103 /**********************************************************************
104 **********************************************************************/
105 static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
106 uint32 returned, PRINTER_INFO_2 **info)
108 uint32 i;
109 PRINTER_INFO_2 *inf;
111 inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
113 buffer->prs.data_offset=0;
115 for (i=0; i<returned; i++) {
116 /* a little initialization as we go */
117 inf[i].secdesc = NULL;
118 smb_io_printer_info_2("", buffer, &inf[i], 0);
121 *info=inf;
124 /**********************************************************************
125 **********************************************************************/
126 static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
127 uint32 returned, PRINTER_INFO_3 **info)
129 uint32 i;
130 PRINTER_INFO_3 *inf;
132 inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
134 buffer->prs.data_offset=0;
136 for (i=0; i<returned; i++) {
137 inf[i].secdesc = NULL;
138 smb_io_printer_info_3("", buffer, &inf[i], 0);
141 *info=inf;
144 /**********************************************************************
145 **********************************************************************/
146 static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
147 uint32 returned, PORT_INFO_1 **info)
149 uint32 i;
150 PORT_INFO_1 *inf;
152 inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
154 prs_set_offset(&buffer->prs, 0);
156 for (i=0; i<returned; i++) {
157 smb_io_port_info_1("", buffer, &(inf[i]), 0);
160 *info=inf;
163 /**********************************************************************
164 **********************************************************************/
165 static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
166 uint32 returned, PORT_INFO_2 **info)
168 uint32 i;
169 PORT_INFO_2 *inf;
171 inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
173 prs_set_offset(&buffer->prs, 0);
175 for (i=0; i<returned; i++) {
176 smb_io_port_info_2("", buffer, &(inf[i]), 0);
179 *info=inf;
182 /**********************************************************************
183 **********************************************************************/
184 static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
185 uint32 returned, DRIVER_INFO_1 **info)
187 uint32 i;
188 DRIVER_INFO_1 *inf;
190 inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
192 buffer->prs.data_offset=0;
194 for (i=0; i<returned; i++) {
195 smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
198 *info=inf;
201 /**********************************************************************
202 **********************************************************************/
203 static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
204 uint32 returned, DRIVER_INFO_2 **info)
206 uint32 i;
207 DRIVER_INFO_2 *inf;
209 inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
211 buffer->prs.data_offset=0;
213 for (i=0; i<returned; i++) {
214 smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
217 *info=inf;
220 /**********************************************************************
221 **********************************************************************/
222 static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
223 uint32 returned, DRIVER_INFO_3 **info)
225 uint32 i;
226 DRIVER_INFO_3 *inf;
228 inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
230 buffer->prs.data_offset=0;
232 for (i=0; i<returned; i++) {
233 smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
236 *info=inf;
239 /**********************************************************************
240 **********************************************************************/
241 static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
242 uint32 returned, DRIVER_DIRECTORY_1 **info
245 DRIVER_DIRECTORY_1 *inf;
247 inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
249 prs_set_offset(&buffer->prs, 0);
251 smb_io_driverdir_1("", buffer, inf, 0);
253 *info=inf;
256 /** Return a handle to the specified printer or print server.
258 * @param cli Pointer to client state structure which is open
259 * on the SPOOLSS pipe.
261 * @param mem_ctx Pointer to an initialised talloc context.
263 * @param printername The name of the printer or print server to be
264 * opened in UNC format.
266 * @param datatype Specifies the default data type for the printer.
268 * @param access_required The access rights requested on the printer or
269 * print server.
271 * @param station The UNC name of the requesting workstation.
273 * @param username The name of the user requesting the open.
275 * @param pol Returned policy handle.
278 /*********************************************************************************
279 Win32 API - OpenPrinter()
280 ********************************************************************************/
282 WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
283 char *printername, char *datatype, uint32 access_required,
284 char *station, char *username, POLICY_HND *pol)
286 prs_struct qbuf, rbuf;
287 SPOOL_Q_OPEN_PRINTER_EX q;
288 SPOOL_R_OPEN_PRINTER_EX r;
289 WERROR result = W_ERROR(ERRgeneral);
291 ZERO_STRUCT(q);
292 ZERO_STRUCT(r);
294 /* Initialise parse structures */
296 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
297 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
299 /* Initialise input parameters */
301 make_spoolss_q_open_printer_ex(&q, printername, datatype,
302 access_required, station, username);
304 /* Marshall data and send request */
306 if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
307 !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
308 goto done;
310 /* Unmarshall response */
312 if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0))
313 goto done;
315 /* Return output parameters */
317 result = r.status;
319 if (W_ERROR_IS_OK(result))
320 *pol = r.handle;
322 done:
323 prs_mem_free(&qbuf);
324 prs_mem_free(&rbuf);
326 return result;
329 /** Close a printer handle
331 * @param cli Pointer to client state structure which is open
332 * on the SPOOLSS pipe.
334 * @param mem_ctx Pointer to an initialised talloc context.
336 * @param pol Policy handle of printer or print server to close.
338 /*********************************************************************************
339 Win32 API - ClosePrinter()
340 ********************************************************************************/
342 WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
343 POLICY_HND *pol)
345 prs_struct qbuf, rbuf;
346 SPOOL_Q_CLOSEPRINTER q;
347 SPOOL_R_CLOSEPRINTER r;
348 WERROR result = W_ERROR(ERRgeneral);
350 ZERO_STRUCT(q);
351 ZERO_STRUCT(r);
353 /* Initialise parse structures */
355 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
356 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
358 /* Initialise input parameters */
360 make_spoolss_q_closeprinter(&q, pol);
362 /* Marshall data and send request */
364 if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
365 !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
366 goto done;
368 /* Unmarshall response */
370 if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0))
371 goto done;
373 /* Return output parameters */
375 result = r.status;
377 if (W_ERROR_IS_OK(result))
378 *pol = r.handle;
380 done:
381 prs_mem_free(&qbuf);
382 prs_mem_free(&rbuf);
384 return result;
387 /** Enumerate printers on a print server.
389 * @param cli Pointer to client state structure which is open
390 * on the SPOOLSS pipe.
391 * @param mem_ctx Pointer to an initialised talloc context.
393 * @param offered Buffer size offered in the request.
394 * @param needed Number of bytes needed to complete the request.
395 * may be NULL.
397 * @param flags Selected from PRINTER_ENUM_* flags.
398 * @param level Request information level.
400 * @param num_printers Pointer to number of printers returned. May be
401 * NULL.
402 * @param ctr Return structure for printer information. May
403 * be NULL.
405 /*********************************************************************************
406 Win32 API - EnumPrinters()
407 ********************************************************************************/
409 WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
410 uint32 offered, uint32 *needed,
411 uint32 flags, uint32 level,
412 uint32 *num_printers, PRINTER_INFO_CTR *ctr)
414 prs_struct qbuf, rbuf;
415 SPOOL_Q_ENUMPRINTERS q;
416 SPOOL_R_ENUMPRINTERS r;
417 NEW_BUFFER buffer;
418 WERROR result = W_ERROR(ERRgeneral);
419 fstring server;
421 ZERO_STRUCT(q);
422 ZERO_STRUCT(r);
424 fstrcpy (server, cli->desthost);
425 strupper (server);
427 /* Initialise input parameters */
429 init_buffer(&buffer, offered, mem_ctx);
431 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
432 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
434 make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
435 offered);
437 /* Marshall data and send request */
439 if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
440 !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
441 goto done;
443 /* Unmarshall response */
445 if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
446 if (needed)
447 *needed = r.needed;
450 result = r.status;
452 /* Return output parameters */
454 if (!W_ERROR_IS_OK(r.status))
455 goto done;
457 if (num_printers)
458 *num_printers = r.returned;
460 if (!ctr)
461 goto done;
463 switch (level) {
464 case 0:
465 decode_printer_info_0(mem_ctx, r.buffer, r.returned,
466 &ctr->printers_0);
467 break;
468 case 1:
469 decode_printer_info_1(mem_ctx, r.buffer, r.returned,
470 &ctr->printers_1);
471 break;
472 case 2:
473 decode_printer_info_2(mem_ctx, r.buffer, r.returned,
474 &ctr->printers_2);
475 break;
476 case 3:
477 decode_printer_info_3(mem_ctx, r.buffer, r.returned,
478 &ctr->printers_3);
479 break;
482 done:
483 prs_mem_free(&qbuf);
484 prs_mem_free(&rbuf);
486 return result;
489 /*********************************************************************************
490 Win32 API - EnumPorts()
491 ********************************************************************************/
492 /** Enumerate printer ports on a print server.
494 * @param cli Pointer to client state structure which is open
495 * on the SPOOLSS pipe.
496 * @param mem_ctx Pointer to an initialised talloc context.
498 * @param offered Buffer size offered in the request.
499 * @param needed Number of bytes needed to complete the request.
500 * May be NULL.
502 * @param level Requested information level.
504 * @param num_ports Pointer to number of ports returned. May be NULL.
505 * @param ctr Pointer to structure holding port information.
506 * May be NULL.
509 WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
510 uint32 offered, uint32 *needed,
511 uint32 level, int *num_ports, PORT_INFO_CTR *ctr)
513 prs_struct qbuf, rbuf;
514 SPOOL_Q_ENUMPORTS q;
515 SPOOL_R_ENUMPORTS r;
516 NEW_BUFFER buffer;
517 WERROR result = W_ERROR(ERRgeneral);
518 fstring server;
520 ZERO_STRUCT(q);
521 ZERO_STRUCT(r);
523 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
524 strupper (server);
526 /* Initialise input parameters */
528 init_buffer(&buffer, offered, mem_ctx);
530 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
531 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
533 make_spoolss_q_enumports(&q, server, level, &buffer, offered);
535 /* Marshall data and send request */
537 if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
538 !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
539 goto done;
541 /* Unmarshall response */
543 if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
544 if (needed)
545 *needed = r.needed;
548 result = r.status;
550 /* Return output parameters */
552 if (!W_ERROR_IS_OK(result))
553 goto done;
555 if (num_ports)
556 *num_ports = r.returned;
558 if (!ctr)
559 goto done;
561 switch (level) {
562 case 1:
563 decode_port_info_1(mem_ctx, r.buffer, r.returned,
564 &ctr->port.info_1);
565 break;
566 case 2:
567 decode_port_info_2(mem_ctx, r.buffer, r.returned,
568 &ctr->port.info_2);
569 break;
572 done:
573 prs_mem_free(&qbuf);
574 prs_mem_free(&rbuf);
576 return result;
579 /*********************************************************************************
580 Win32 API - GetPrinter()
581 ********************************************************************************/
583 WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
584 uint32 offered, uint32 *needed,
585 POLICY_HND *pol, uint32 level,
586 PRINTER_INFO_CTR *ctr)
588 prs_struct qbuf, rbuf;
589 SPOOL_Q_GETPRINTER q;
590 SPOOL_R_GETPRINTER r;
591 NEW_BUFFER buffer;
592 WERROR result = W_ERROR(ERRgeneral);
594 ZERO_STRUCT(q);
595 ZERO_STRUCT(r);
597 /* Initialise input parameters */
599 init_buffer(&buffer, offered, mem_ctx);
601 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
602 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
604 make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered);
606 /* Marshall data and send request */
608 if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
609 !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
610 goto done;
612 /* Unmarshall response */
614 if (!spoolss_io_r_getprinter("", &r, &rbuf, 0))
615 goto done;
617 if (needed)
618 *needed = r.needed;
620 /* Return output parameters */
622 result = r.status;
624 if (NT_STATUS_IS_OK(result)) {
625 switch (level) {
626 case 0:
627 decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
628 break;
629 case 1:
630 decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
631 break;
632 case 2:
633 decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
634 break;
635 case 3:
636 decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
637 break;
641 done:
642 prs_mem_free(&qbuf);
643 prs_mem_free(&rbuf);
645 return result;
648 /*********************************************************************************
649 Win32 API - SetPrinter()
650 ********************************************************************************/
651 /** Set printer info
653 * @param cli Pointer to client state structure which is open
654 * on the SPOOLSS pipe.
655 * @param mem_ctx Pointer to an initialised talloc context.
657 * @param pol Policy handle on printer to set info.
658 * @param level Information level to set.
659 * @param ctr Pointer to structure holding printer information.
660 * @param command Specifies the action performed. See
661 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp
662 * for details.
666 WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
667 POLICY_HND *pol, uint32 level,
668 PRINTER_INFO_CTR *ctr, uint32 command)
670 prs_struct qbuf, rbuf;
671 SPOOL_Q_SETPRINTER q;
672 SPOOL_R_SETPRINTER r;
673 WERROR result = W_ERROR(ERRgeneral);
675 ZERO_STRUCT(q);
676 ZERO_STRUCT(r);
678 /* Initialise input parameters */
679 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
680 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
682 make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
684 /* Marshall data and send request */
686 if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
687 !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
688 goto done;
690 /* Unmarshall response */
692 if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
693 goto done;
695 result = r.status;
697 done:
698 prs_mem_free(&qbuf);
699 prs_mem_free(&rbuf);
702 return result;
705 /*********************************************************************************
706 Win32 API - GetPrinterDriver()
707 ********************************************************************************/
708 /** Get installed printer drivers for a given printer
710 * @param cli Pointer to client state structure which is open
711 * on the SPOOLSS pipe.
713 * @param mem_ctx Pointer to an initialised talloc context.
715 * @param offered Buffer size offered in the request.
716 * @param needed Number of bytes needed to complete the request.
717 * may be NULL.
719 * @param pol Pointer to an open policy handle for the printer
720 * opened with cli_spoolss_open_printer_ex().
721 * @param level Requested information level.
722 * @param env The print environment or archictecture. This is
723 * "Windows NT x86" for NT4.
724 * @param ctr Returned printer driver information.
727 WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
728 TALLOC_CTX *mem_ctx,
729 uint32 offered, uint32 *needed,
730 POLICY_HND *pol, uint32 level,
731 char *env, PRINTER_DRIVER_CTR *ctr)
733 prs_struct qbuf, rbuf;
734 SPOOL_Q_GETPRINTERDRIVER2 q;
735 SPOOL_R_GETPRINTERDRIVER2 r;
736 NEW_BUFFER buffer;
737 WERROR result = W_ERROR(ERRgeneral);
738 fstring server;
740 ZERO_STRUCT(q);
741 ZERO_STRUCT(r);
743 fstrcpy (server, cli->desthost);
744 strupper (server);
746 /* Initialise input parameters */
748 init_buffer(&buffer, offered, mem_ctx);
750 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
751 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
753 make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2,
754 &buffer, offered);
756 /* Marshall data and send request */
758 if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
759 !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
760 goto done;
762 /* Unmarshall response */
764 if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) {
765 if (needed)
766 *needed = r.needed;
769 result = r.status;
771 /* Return output parameters */
773 if (!W_ERROR_IS_OK(result))
774 goto done;
776 if (!ctr)
777 goto done;
779 switch (level) {
780 case 1:
781 decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
782 break;
783 case 2:
784 decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
785 break;
786 case 3:
787 decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
788 break;
791 done:
792 prs_mem_free(&qbuf);
793 prs_mem_free(&rbuf);
795 return result;
798 /*********************************************************************************
799 Win32 API - EnumPrinterDrivers()
800 ********************************************************************************/
801 /**********************************************************************
802 * Get installed printer drivers for a given printer
804 WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
805 TALLOC_CTX *mem_ctx,
806 uint32 offered, uint32 *needed,
807 uint32 level, char *env,
808 uint32 *num_drivers,
809 PRINTER_DRIVER_CTR *ctr)
811 prs_struct qbuf, rbuf;
812 SPOOL_Q_ENUMPRINTERDRIVERS q;
813 SPOOL_R_ENUMPRINTERDRIVERS r;
814 NEW_BUFFER buffer;
815 WERROR result = W_ERROR(ERRgeneral);
816 fstring server;
818 ZERO_STRUCT(q);
819 ZERO_STRUCT(r);
821 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
822 strupper (server);
824 /* Initialise input parameters */
826 init_buffer(&buffer, offered, mem_ctx);
828 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
829 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
831 /* Write the request */
833 make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer,
834 offered);
836 /* Marshall data and send request */
838 if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
839 !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
840 goto done;
842 /* Unmarshall response */
844 if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
845 goto done;
847 if (needed)
848 *needed = r.needed;
850 if (num_drivers)
851 *num_drivers = r.returned;
853 result = r.status;
855 /* Return output parameters */
857 if (W_ERROR_IS_OK(result) && (r.returned != 0)) {
858 *num_drivers = r.returned;
860 switch (level) {
861 case 1:
862 decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
863 break;
864 case 2:
865 decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
866 break;
867 case 3:
868 decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
869 break;
873 done:
874 prs_mem_free(&qbuf);
875 prs_mem_free(&rbuf);
877 return result;
881 /*********************************************************************************
882 Win32 API - GetPrinterDriverDirectory()
883 ********************************************************************************/
884 /**********************************************************************
885 * Get installed printer drivers for a given printer
887 WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
888 TALLOC_CTX *mem_ctx,
889 uint32 offered, uint32 *needed,
890 uint32 level, char *env,
891 DRIVER_DIRECTORY_CTR *ctr)
893 prs_struct qbuf, rbuf;
894 SPOOL_Q_GETPRINTERDRIVERDIR q;
895 SPOOL_R_GETPRINTERDRIVERDIR r;
896 NEW_BUFFER buffer;
897 WERROR result = W_ERROR(ERRgeneral);
898 fstring server;
900 ZERO_STRUCT(q);
901 ZERO_STRUCT(r);
903 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
904 strupper (server);
906 /* Initialise input parameters */
908 init_buffer(&buffer, offered, mem_ctx);
910 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
911 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
913 /* Write the request */
915 make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer,
916 offered);
918 /* Marshall data and send request */
920 if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
921 !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
922 &qbuf, &rbuf))
923 goto done;
925 /* Unmarshall response */
927 if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) {
928 if (needed)
929 *needed = r.needed;
932 /* Return output parameters */
934 result = r.status;
936 if (W_ERROR_IS_OK(result)) {
937 switch (level) {
938 case 1:
939 decode_printerdriverdir_1(mem_ctx, r.buffer, 1,
940 &ctr->info1);
941 break;
945 done:
946 prs_mem_free(&qbuf);
947 prs_mem_free(&rbuf);
949 return result;
952 /*********************************************************************************
953 Win32 API - AddPrinterDriver()
954 ********************************************************************************/
955 /**********************************************************************
956 * Install a printer driver
958 WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
959 TALLOC_CTX *mem_ctx, uint32 level,
960 PRINTER_DRIVER_CTR *ctr)
962 prs_struct qbuf, rbuf;
963 SPOOL_Q_ADDPRINTERDRIVER q;
964 SPOOL_R_ADDPRINTERDRIVER r;
965 WERROR result = W_ERROR(ERRgeneral);
966 fstring server;
968 ZERO_STRUCT(q);
969 ZERO_STRUCT(r);
971 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
972 strupper (server);
974 /* Initialise input parameters */
975 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
976 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
978 /* Write the request */
980 make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr);
982 /* Marshall data and send request */
984 if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
985 !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
986 goto done;
988 /* Unmarshall response */
990 if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
991 goto done;
993 /* Return output parameters */
995 result = r.status;
997 done:
998 prs_mem_free(&qbuf);
999 prs_mem_free(&rbuf);
1001 return result;
1004 /*********************************************************************************
1005 Win32 API - AddPrinter()
1006 ********************************************************************************/
1007 /**********************************************************************
1008 * Install a printer
1010 WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
1011 uint32 level, PRINTER_INFO_CTR*ctr)
1013 prs_struct qbuf, rbuf;
1014 SPOOL_Q_ADDPRINTEREX q;
1015 SPOOL_R_ADDPRINTEREX r;
1016 WERROR result = W_ERROR(ERRgeneral);
1017 fstring server,
1018 client,
1019 user;
1021 ZERO_STRUCT(q);
1022 ZERO_STRUCT(r);
1024 slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1025 strupper (client);
1026 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1027 strupper (server);
1028 fstrcpy (user, cli->user_name);
1030 /* Initialise input parameters */
1032 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1033 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1035 /* Write the request */
1037 make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user,
1038 level, ctr);
1040 /* Marshall data and send request */
1042 if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
1043 !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
1044 goto done;
1046 /* Unmarshall response */
1048 if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
1049 goto done;
1051 /* Return output parameters */
1053 result = r.status;
1055 done:
1056 prs_mem_free(&qbuf);
1057 prs_mem_free(&rbuf);
1059 return result;
1062 /*********************************************************************************
1063 Win32 API - DeltePrinterDriver()
1064 ********************************************************************************/
1065 /**********************************************************************
1066 * Delete a Printer Driver from the server (does not remove
1067 * the driver files
1069 WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
1070 TALLOC_CTX *mem_ctx, char *arch,
1071 char *driver)
1073 prs_struct qbuf, rbuf;
1074 SPOOL_Q_DELETEPRINTERDRIVER q;
1075 SPOOL_R_DELETEPRINTERDRIVER r;
1076 WERROR result = W_ERROR(ERRgeneral);
1077 fstring server;
1079 ZERO_STRUCT(q);
1080 ZERO_STRUCT(r);
1083 /* Initialise input parameters */
1084 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1085 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1087 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1088 strupper (server);
1090 /* Write the request */
1092 make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver);
1094 /* Marshall data and send request */
1096 if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
1097 !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
1098 goto done;
1100 /* Unmarshall response */
1102 if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0))
1103 goto done;
1105 /* Return output parameters */
1107 result = r.status;
1109 done:
1110 prs_mem_free(&qbuf);
1111 prs_mem_free(&rbuf);
1113 return result;
1116 /*********************************************************************************
1117 Win32 API - GetPrinterProcessorDirectory()
1118 ********************************************************************************/
1120 WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
1121 TALLOC_CTX *mem_ctx,
1122 uint32 offered, uint32 *needed,
1123 char *name, char *environment,
1124 fstring procdir)
1126 prs_struct qbuf, rbuf;
1127 SPOOL_Q_GETPRINTPROCESSORDIRECTORY q;
1128 SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
1129 int level = 1;
1130 WERROR result = W_ERROR(ERRgeneral);
1131 NEW_BUFFER buffer;
1133 ZERO_STRUCT(q);
1134 ZERO_STRUCT(r);
1136 /* Initialise parse structures */
1138 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1139 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1141 /* Initialise input parameters */
1143 init_buffer(&buffer, offered, mem_ctx);
1145 make_spoolss_q_getprintprocessordirectory(
1146 &q, name, environment, level, &buffer, offered);
1148 /* Marshall data and send request */
1150 if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
1151 !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1152 &qbuf, &rbuf))
1153 goto done;
1155 /* Unmarshall response */
1157 if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0))
1158 goto done;
1160 /* Return output parameters */
1162 result = r.status;
1164 if (needed)
1165 *needed = r.needed;
1167 if (W_ERROR_IS_OK(result))
1168 fstrcpy(procdir, "Not implemented!");
1170 done:
1171 prs_mem_free(&qbuf);
1172 prs_mem_free(&rbuf);
1174 return result;
1177 /** Add a form to a printer.
1179 * @param cli Pointer to client state structure which is open
1180 * on the SPOOLSS pipe.
1181 * @param mem_ctx Pointer to an initialised talloc context.
1183 * @param handle Policy handle opened with cli_spoolss_open_printer_ex
1184 * or cli_spoolss_addprinterex.
1185 * @param level Form info level to add - should always be 1.
1186 * @param form A pointer to the form to be added.
1190 WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1191 POLICY_HND *handle, uint32 level, FORM *form)
1193 prs_struct qbuf, rbuf;
1194 SPOOL_Q_ADDFORM q;
1195 SPOOL_R_ADDFORM r;
1196 WERROR result = W_ERROR(ERRgeneral);
1198 ZERO_STRUCT(q);
1199 ZERO_STRUCT(r);
1201 /* Initialise parse structures */
1203 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1204 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1206 /* Initialise input parameters */
1208 make_spoolss_q_addform(&q, handle, level, form);
1210 /* Marshall data and send request */
1212 if (!spoolss_io_q_addform("", &q, &qbuf, 0) ||
1213 !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf))
1214 goto done;
1216 /* Unmarshall response */
1218 if (!spoolss_io_r_addform("", &r, &rbuf, 0))
1219 goto done;
1221 /* Return output parameters */
1223 result = r.status;
1225 done:
1226 prs_mem_free(&qbuf);
1227 prs_mem_free(&rbuf);
1229 return result;
1232 /** Set a form on a printer.
1234 * @param cli Pointer to client state structure which is open
1235 * on the SPOOLSS pipe.
1236 * @param mem_ctx Pointer to an initialised talloc context.
1238 * @param handle Policy handle opened with cli_spoolss_open_printer_ex
1239 * or cli_spoolss_addprinterex.
1240 * @param level Form info level to set - should always be 1.
1241 * @param form A pointer to the form to be set.
1245 WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1246 POLICY_HND *handle, uint32 level, char *form_name,
1247 FORM *form)
1249 prs_struct qbuf, rbuf;
1250 SPOOL_Q_SETFORM q;
1251 SPOOL_R_SETFORM r;
1252 WERROR result = W_ERROR(ERRgeneral);
1254 ZERO_STRUCT(q);
1255 ZERO_STRUCT(r);
1257 /* Initialise parse structures */
1259 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1260 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1262 /* Initialise input parameters */
1264 make_spoolss_q_setform(&q, handle, level, form_name, form);
1266 /* Marshall data and send request */
1268 if (!spoolss_io_q_setform("", &q, &qbuf, 0) ||
1269 !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf))
1270 goto done;
1272 /* Unmarshall response */
1274 if (!spoolss_io_r_setform("", &r, &rbuf, 0))
1275 goto done;
1277 /* Return output parameters */
1279 result = r.status;
1281 if (!W_ERROR_IS_OK(result))
1282 goto done;
1286 done:
1287 prs_mem_free(&qbuf);
1288 prs_mem_free(&rbuf);
1290 return result;
1293 /** Get a form on a printer.
1295 * @param cli Pointer to client state structure which is open
1296 * on the SPOOLSS pipe.
1297 * @param mem_ctx Pointer to an initialised talloc context.
1299 * @param handle Policy handle opened with cli_spoolss_open_printer_ex
1300 * or cli_spoolss_addprinterex.
1301 * @param formname Name of the form to get
1302 * @param level Form info level to get - should always be 1.
1306 WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1307 uint32 offered, uint32 *needed,
1308 POLICY_HND *handle, char *formname, uint32 level,
1309 FORM_1 *form)
1311 prs_struct qbuf, rbuf;
1312 SPOOL_Q_GETFORM q;
1313 SPOOL_R_GETFORM r;
1314 WERROR result = W_ERROR(ERRgeneral);
1315 NEW_BUFFER buffer;
1317 ZERO_STRUCT(q);
1318 ZERO_STRUCT(r);
1320 /* Initialise parse structures */
1322 init_buffer(&buffer, offered, mem_ctx);
1324 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1325 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1327 /* Initialise input parameters */
1329 make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered);
1331 /* Marshall data and send request */
1333 if (!spoolss_io_q_getform("", &q, &qbuf, 0) ||
1334 !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf))
1335 goto done;
1337 /* Unmarshall response */
1339 if (!spoolss_io_r_getform("", &r, &rbuf, 0))
1340 goto done;
1342 /* Return output parameters */
1344 result = r.status;
1346 if (needed)
1347 *needed = r.needed;
1349 if (W_ERROR_IS_OK(result))
1350 smb_io_form_1("", r.buffer, form, 0);
1352 done:
1353 prs_mem_free(&qbuf);
1354 prs_mem_free(&rbuf);
1356 return result;
1359 /** Delete a form on a printer.
1361 * @param cli Pointer to client state structure which is open
1362 * on the SPOOLSS pipe.
1363 * @param mem_ctx Pointer to an initialised talloc context.
1365 * @param handle Policy handle opened with cli_spoolss_open_printer_ex
1366 * or cli_spoolss_addprinterex.
1367 * @param form The name of the form to delete.
1371 WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1372 POLICY_HND *handle, char *form_name)
1374 prs_struct qbuf, rbuf;
1375 SPOOL_Q_DELETEFORM q;
1376 SPOOL_R_DELETEFORM r;
1377 WERROR result = W_ERROR(ERRgeneral);
1379 ZERO_STRUCT(q);
1380 ZERO_STRUCT(r);
1382 /* Initialise parse structures */
1384 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1385 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1387 /* Initialise input parameters */
1389 make_spoolss_q_deleteform(&q, handle, form_name);
1391 /* Marshall data and send request */
1393 if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) ||
1394 !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
1395 goto done;
1397 /* Unmarshall response */
1399 if (!spoolss_io_r_deleteform("", &r, &rbuf, 0))
1400 goto done;
1402 /* Return output parameters */
1404 result = r.status;
1406 done:
1407 prs_mem_free(&qbuf);
1408 prs_mem_free(&rbuf);
1410 return result;
1413 static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
1414 uint32 num_forms, FORM_1 **forms)
1416 int i;
1418 *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
1419 buffer->prs.data_offset = 0;
1421 for (i = 0; i < num_forms; i++)
1422 smb_io_form_1("", buffer, &((*forms)[i]), 0);
1425 /** Enumerate forms
1427 * @param cli Pointer to client state structure which is open
1428 * on the SPOOLSS pipe.
1429 * @param mem_ctx Pointer to an initialised talloc context.
1431 * @param offered Buffer size offered in the request.
1432 * @param needed Number of bytes needed to complete the request.
1433 * may be NULL.
1434 * or cli_spoolss_addprinterex.
1435 * @param level Form info level to get - should always be 1.
1436 * @param handle Open policy handle
1440 WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1441 uint32 offered, uint32 *needed,
1442 POLICY_HND *handle, int level, uint32 *num_forms,
1443 FORM_1 **forms)
1445 prs_struct qbuf, rbuf;
1446 SPOOL_Q_ENUMFORMS q;
1447 SPOOL_R_ENUMFORMS r;
1448 WERROR result = W_ERROR(ERRgeneral);
1449 NEW_BUFFER buffer;
1451 ZERO_STRUCT(q);
1452 ZERO_STRUCT(r);
1454 /* Initialise parse structures */
1456 init_buffer(&buffer, offered, mem_ctx);
1458 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1459 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1461 /* Initialise input parameters */
1463 make_spoolss_q_enumforms(&q, handle, level, &buffer, offered);
1465 /* Marshall data and send request */
1467 if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) ||
1468 !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
1469 goto done;
1471 /* Unmarshall response */
1473 if (!spoolss_io_r_enumforms("", &r, &rbuf, 0))
1474 goto done;
1476 /* Return output parameters */
1478 result = r.status;
1480 if (needed)
1481 *needed = r.needed;
1483 if (num_forms)
1484 *num_forms = r.numofforms;
1486 decode_forms_1(mem_ctx, r.buffer, *num_forms, forms);
1488 done:
1489 prs_mem_free(&qbuf);
1490 prs_mem_free(&rbuf);
1492 return result;
1495 /*********************************************************************************
1496 Win32 API - SetPrinterData()
1497 ********************************************************************************/
1499 WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx,
1500 POLICY_HND *pol, char* valname, char* value)
1502 prs_struct qbuf, rbuf;
1503 SPOOL_Q_SETPRINTERDATA q;
1504 SPOOL_R_SETPRINTERDATA r;
1505 WERROR result = W_ERROR(ERRgeneral);
1507 ZERO_STRUCT(q);
1508 ZERO_STRUCT(r);
1510 /* Initialise input parameters */
1512 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1513 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1516 /* write the request */
1517 make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value);
1519 /* Marshall data and send request */
1520 if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) ||
1521 !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
1522 goto done;
1524 /* Unmarshall response */
1525 if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0))
1526 goto done;
1528 result = r.status;
1530 done:
1531 prs_mem_free(&qbuf);
1532 prs_mem_free(&rbuf);
1534 return result;
1538 /** @} **/