2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
26 #include "rpcclient.h"
27 #include "../librpc/gen_ndr/cli_spoolss.h"
29 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
31 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
32 _cli->srv_name_slash, _arg); \
33 W_ERROR_HAVE_NO_MEMORY(_printername); \
36 /* The version int is used by getdrivers. Note that
37 all architecture strings that support mutliple
38 versions must be grouped together since enumdrivers
39 uses this property to prevent issuing multiple
40 enumdriver calls for the same arch */
43 static const struct print_architecture_table_node archi_table
[]= {
45 {"Windows 4.0", "WIN40", 0 },
46 {"Windows NT x86", "W32X86", 2 },
47 {"Windows NT x86", "W32X86", 3 },
48 {"Windows NT R4000", "W32MIPS", 2 },
49 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
50 {"Windows NT PowerPC", "W32PPC", 2 },
51 {"Windows IA64", "IA64", 3 },
52 {"Windows x64", "x64", 3 },
59 * rpcclient module for SPOOLSS rpc pipe.
61 * This generally just parses and checks command lines, and then calls
62 * a cli_spoolss function.
65 /****************************************************************************
66 function to do the mapping between the long architecture name and
68 ****************************************************************************/
70 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
74 DEBUG(107,("Getting architecture dependant directory\n"));
77 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
78 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
80 if (archi_table
[i
].long_archi
==NULL
) {
81 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
85 /* this might be client code - but shouldn't this be an fstrcpy etc? */
88 DEBUGADD(108,("index: [%d]\n", i
));
89 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
90 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
92 return archi_table
[i
].short_archi
;
95 /****************************************************************************
96 ****************************************************************************/
98 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
100 int argc
, const char **argv
)
103 struct policy_handle hnd
;
106 printf("Usage: %s <printername>\n", argv
[0]);
111 return WERR_GENERAL_FAILURE
;
113 /* Open the printer handle */
115 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
119 if (W_ERROR_IS_OK(werror
)) {
120 printf("Printer %s opened successfully\n", argv
[1]);
121 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
123 if (!W_ERROR_IS_OK(werror
)) {
124 printf("Error closing printer handle! (%s)\n",
125 get_dos_error_msg(werror
));
133 /****************************************************************************
134 ****************************************************************************/
136 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
141 printf("\tprintername:[%s]\n", r
->printername
);
142 printf("\tservername:[%s]\n", r
->servername
);
143 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
144 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
145 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
146 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
147 r
->time
.day
, r
->time
.day_of_week
);
148 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
149 r
->time
.second
, r
->time
.millisecond
);
151 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
152 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
154 printf("\tversion:[0x%x]\n", r
->version
);
155 printf("\tfree_build:[0x%x]\n", r
->free_build
);
156 printf("\tspooling:[0x%x]\n", r
->spooling
);
157 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
158 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
159 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
160 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
161 printf("\tjob_error:[0x%x]\n", r
->job_error
);
162 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
163 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
164 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
165 printf("\tchange_id:[0x%x]\n", r
->change_id
);
166 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
167 printf("\tstatus:[0x%x]\n", r
->status
);
168 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
169 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
170 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
171 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
172 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
173 printf("\treserved2:[0x%x]\n", r
->reserved2
);
174 printf("\treserved3:[0x%x]\n", r
->reserved3
);
179 /****************************************************************************
180 ****************************************************************************/
182 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
184 printf("\tflags:[0x%x]\n", r
->flags
);
185 printf("\tname:[%s]\n", r
->name
);
186 printf("\tdescription:[%s]\n", r
->description
);
187 printf("\tcomment:[%s]\n", r
->comment
);
192 /****************************************************************************
193 ****************************************************************************/
195 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
197 printf("\tservername:[%s]\n", r
->servername
);
198 printf("\tprintername:[%s]\n", r
->printername
);
199 printf("\tsharename:[%s]\n", r
->sharename
);
200 printf("\tportname:[%s]\n", r
->portname
);
201 printf("\tdrivername:[%s]\n", r
->drivername
);
202 printf("\tcomment:[%s]\n", r
->comment
);
203 printf("\tlocation:[%s]\n", r
->location
);
204 printf("\tsepfile:[%s]\n", r
->sepfile
);
205 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
206 printf("\tdatatype:[%s]\n", r
->datatype
);
207 printf("\tparameters:[%s]\n", r
->parameters
);
208 printf("\tattributes:[0x%x]\n", r
->attributes
);
209 printf("\tpriority:[0x%x]\n", r
->priority
);
210 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
211 printf("\tstarttime:[0x%x]\n", r
->starttime
);
212 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
213 printf("\tstatus:[0x%x]\n", r
->status
);
214 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
215 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
218 display_sec_desc(r
->secdesc
);
223 /****************************************************************************
224 ****************************************************************************/
226 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
228 display_sec_desc(r
->secdesc
);
233 /****************************************************************************
234 ****************************************************************************/
236 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
238 printf("\tservername:[%s]\n", r
->servername
);
239 printf("\tprintername:[%s]\n", r
->printername
);
240 printf("\tattributes:[0x%x]\n", r
->attributes
);
244 /****************************************************************************
245 ****************************************************************************/
247 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
249 printf("\tprintername:[%s]\n", r
->printername
);
250 printf("\tportname:[%s]\n", r
->portname
);
251 printf("\tattributes:[0x%x]\n", r
->attributes
);
252 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
253 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
257 /****************************************************************************
258 ****************************************************************************/
260 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
262 printf("\tstatus:[0x%x]\n", r
->status
);
266 /****************************************************************************
267 ****************************************************************************/
269 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
271 printf("\tguid:[%s]\n", r
->guid
);
272 printf("\taction:[0x%x]\n", r
->action
);
276 /****************************************************************************
277 ****************************************************************************/
279 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
281 int argc
, const char **argv
)
285 union spoolss_PrinterInfo
*info
;
288 uint32_t flags
= PRINTER_ENUM_LOCAL
;
291 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
296 level
= atoi(argv
[1]);
302 name
= cli
->srv_name_slash
;
306 flags
= atoi(argv
[3]);
309 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
316 if (W_ERROR_IS_OK(result
)) {
319 printf ("No printers returned.\n");
323 for (i
= 0; i
< count
; i
++) {
326 display_print_info0(&info
[i
].info0
);
329 display_print_info1(&info
[i
].info1
);
332 display_print_info2(&info
[i
].info2
);
335 display_print_info3(&info
[i
].info3
);
338 display_print_info4(&info
[i
].info4
);
341 display_print_info5(&info
[i
].info5
);
344 display_print_info6(&info
[i
].info6
);
347 printf("unknown info level %d\n", level
);
357 /****************************************************************************
358 ****************************************************************************/
360 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
362 printf("\tPort Name:\t[%s]\n", r
->port_name
);
365 /****************************************************************************
366 ****************************************************************************/
368 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
370 printf("\tPort Name:\t[%s]\n", r
->port_name
);
371 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
372 printf("\tDescription:\t[%s]\n", r
->description
);
373 printf("\tPort Type:\t" );
375 int comma
= 0; /* hack */
377 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
381 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
382 printf( "%sWrite", comma
? ", " : "" );
385 /* These two have slightly different interpretations
386 on 95/98/ME but I'm disregarding that for now */
387 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
388 printf( "%sRedirected", comma
? ", " : "" );
391 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
392 printf( "%sNet-Attached", comma
? ", " : "" );
396 printf( "[Unset]\n" );
398 printf("\tReserved:\t[%d]\n", r
->reserved
);
402 /****************************************************************************
403 ****************************************************************************/
405 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
406 TALLOC_CTX
*mem_ctx
, int argc
,
412 union spoolss_PortInfo
*info
;
415 printf("Usage: %s [level]\n", argv
[0]);
420 level
= atoi(argv
[1]);
423 /* Enumerate ports */
425 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
431 if (W_ERROR_IS_OK(result
)) {
434 for (i
= 0; i
< count
; i
++) {
437 display_port_info_1(&info
[i
].info1
);
440 display_port_info_2(&info
[i
].info2
);
443 printf("unknown info level %d\n", level
);
452 /****************************************************************************
453 ****************************************************************************/
455 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
457 int argc
, const char **argv
)
459 struct policy_handle pol
;
462 uint32_t info_level
= 2;
463 union spoolss_PrinterInfo info
;
464 struct spoolss_SetPrinterInfoCtr info_ctr
;
465 const char *printername
, *comment
= NULL
;
466 struct spoolss_DevmodeContainer devmode_ctr
;
467 struct sec_desc_buf secdesc_ctr
;
469 if (argc
== 1 || argc
> 3) {
470 printf("Usage: %s printername comment\n", argv
[0]);
475 /* Open a printer handle */
480 ZERO_STRUCT(devmode_ctr
);
481 ZERO_STRUCT(secdesc_ctr
);
483 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
485 /* get a printer handle */
486 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
490 if (!W_ERROR_IS_OK(result
))
493 /* Get printer info */
494 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
499 if (!W_ERROR_IS_OK(result
))
503 /* Modify the comment. */
504 info
.info2
.comment
= comment
;
505 info
.info2
.secdesc
= NULL
;
506 info
.info2
.devmode
= NULL
;
509 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
511 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
518 if (W_ERROR_IS_OK(result
))
519 printf("Success in setting comment.\n");
522 if (is_valid_policy_hnd(&pol
))
523 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
528 /****************************************************************************
529 ****************************************************************************/
531 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
533 int argc
, const char **argv
)
535 struct policy_handle pol
;
538 uint32_t info_level
= 2;
539 union spoolss_PrinterInfo info
;
540 const char *printername
,
541 *new_printername
= NULL
;
542 struct spoolss_SetPrinterInfoCtr info_ctr
;
543 struct spoolss_DevmodeContainer devmode_ctr
;
544 struct sec_desc_buf secdesc_ctr
;
546 ZERO_STRUCT(devmode_ctr
);
547 ZERO_STRUCT(secdesc_ctr
);
549 if (argc
== 1 || argc
> 3) {
550 printf("Usage: %s printername new_printername\n", argv
[0]);
555 /* Open a printer handle */
557 new_printername
= argv
[2];
560 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
562 /* get a printer handle */
563 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
567 if (!W_ERROR_IS_OK(result
))
570 /* Get printer info */
571 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
576 if (!W_ERROR_IS_OK(result
))
579 /* Modify the printername. */
580 info
.info2
.printername
= new_printername
;
581 info
.info2
.devmode
= NULL
;
582 info
.info2
.secdesc
= NULL
;
584 info_ctr
.level
= info_level
;
585 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
587 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
594 if (W_ERROR_IS_OK(result
))
595 printf("Success in setting printername.\n");
598 if (is_valid_policy_hnd(&pol
))
599 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
604 /****************************************************************************
605 ****************************************************************************/
607 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
609 int argc
, const char **argv
)
611 struct policy_handle pol
;
614 const char *printername
;
615 union spoolss_PrinterInfo info
;
617 if (argc
== 1 || argc
> 3) {
618 printf("Usage: %s <printername> [level]\n", argv
[0]);
622 /* Open a printer handle */
624 level
= atoi(argv
[2]);
627 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
629 /* get a printer handle */
631 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
633 SEC_FLAG_MAXIMUM_ALLOWED
,
635 if (!W_ERROR_IS_OK(result
)) {
639 /* Get printer info */
641 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
646 if (!W_ERROR_IS_OK(result
)) {
650 /* Display printer info */
653 display_print_info0(&info
.info0
);
656 display_print_info1(&info
.info1
);
659 display_print_info2(&info
.info2
);
662 display_print_info3(&info
.info3
);
665 display_print_info4(&info
.info4
);
668 display_print_info5(&info
.info5
);
671 display_print_info6(&info
.info6
);
674 display_print_info7(&info
.info7
);
677 printf("unknown info level %d\n", level
);
681 if (is_valid_policy_hnd(&pol
)) {
682 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
688 /****************************************************************************
689 ****************************************************************************/
691 static void display_reg_value(struct regval_blob value
)
693 const char *text
= NULL
;
698 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
699 *((uint32_t *) value
.data_p
));
702 blob
= data_blob_const(value
.data_p
, value
.size
);
703 pull_reg_sz(talloc_tos(), &blob
, &text
);
704 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
707 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
709 printf("%s: REG_BINARY:", value
.valuename
);
711 for (i
=0; i
<len
; i
++) {
712 if (hex
[i
] == '\0') {
727 blob
= data_blob_const(value
.data_p
, value
.size
);
729 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
730 d_printf("pull_reg_multi_sz failed\n");
734 printf("%s: REG_MULTI_SZ: \n", value
.valuename
);
735 for (i
=0; values
[i
] != NULL
; i
++) {
736 d_printf("%s\n", values
[i
]);
742 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
747 /****************************************************************************
748 ****************************************************************************/
750 static void display_printer_data(const char *v
,
751 enum winreg_Type type
,
752 union spoolss_PrinterData
*r
)
758 printf("%s: REG_DWORD: 0x%08x\n", v
, r
->value
);
761 printf("%s: REG_SZ: %s\n", v
, r
->string
);
764 char *hex
= hex_encode_talloc(NULL
,
765 r
->binary
.data
, r
->binary
.length
);
767 printf("%s: REG_BINARY:", v
);
769 for (i
=0; i
<len
; i
++) {
770 if (hex
[i
] == '\0') {
783 printf("%s: REG_MULTI_SZ: ", v
);
784 for (i
=0; r
->string_array
[i
] != NULL
; i
++) {
785 printf("%s ", r
->string_array
[i
]);
790 printf("%s: unknown type 0x%02x:\n", v
, type
);
795 /****************************************************************************
796 ****************************************************************************/
798 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
800 int argc
, const char **argv
)
802 struct policy_handle pol
;
805 const char *valuename
;
806 enum winreg_Type type
;
807 union spoolss_PrinterData data
;
810 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
811 printf("<printername> of . queries print server\n");
816 /* Open a printer handle */
818 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
819 fstrcpy(printername
, cli
->srv_name_slash
);
821 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
822 cli
->srv_name_slash
, argv
[1]);
824 /* get a printer handle */
826 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
828 SEC_FLAG_MAXIMUM_ALLOWED
,
830 if (!W_ERROR_IS_OK(result
))
833 /* Get printer info */
835 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
841 if (!W_ERROR_IS_OK(result
))
844 /* Display printer data */
846 display_printer_data(valuename
, type
, &data
);
849 if (is_valid_policy_hnd(&pol
))
850 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
855 /****************************************************************************
856 ****************************************************************************/
858 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
860 int argc
, const char **argv
)
862 struct policy_handle pol
;
866 const char *valuename
, *keyname
;
868 enum winreg_Type type
;
869 union spoolss_PrinterData data
;
870 uint32_t offered
= 0;
874 printf("Usage: %s <printername> <keyname> <valuename>\n",
876 printf("<printername> of . queries print server\n");
882 /* Open a printer handle */
884 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
885 fstrcpy(printername
, cli
->srv_name_slash
);
887 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
888 cli
->srv_name_slash
, argv
[1]);
890 /* get a printer handle */
892 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
894 SEC_FLAG_MAXIMUM_ALLOWED
,
896 if (!W_ERROR_IS_OK(result
))
899 /* Get printer info */
901 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
910 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
912 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
923 if (!NT_STATUS_IS_OK(status
)) {
927 if (!W_ERROR_IS_OK(result
))
930 /* Display printer data */
932 display_printer_data(valuename
, type
, &data
);
936 if (is_valid_policy_hnd(&pol
))
937 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
942 /****************************************************************************
943 ****************************************************************************/
945 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
951 printf("Printer Driver Info 1:\n");
952 printf("\tDriver Name: [%s]\n", r
->driver_name
);
956 /****************************************************************************
957 ****************************************************************************/
959 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
965 printf("Printer Driver Info 2:\n");
966 printf("\tVersion: [%x]\n", r
->version
);
967 printf("\tDriver Name: [%s]\n", r
->driver_name
);
968 printf("\tArchitecture: [%s]\n", r
->architecture
);
969 printf("\tDriver Path: [%s]\n", r
->driver_path
);
970 printf("\tDatafile: [%s]\n", r
->data_file
);
971 printf("\tConfigfile: [%s]\n", r
->config_file
);
975 /****************************************************************************
976 ****************************************************************************/
978 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
986 printf("Printer Driver Info 3:\n");
987 printf("\tVersion: [%x]\n", r
->version
);
988 printf("\tDriver Name: [%s]\n", r
->driver_name
);
989 printf("\tArchitecture: [%s]\n", r
->architecture
);
990 printf("\tDriver Path: [%s]\n", r
->driver_path
);
991 printf("\tDatafile: [%s]\n", r
->data_file
);
992 printf("\tConfigfile: [%s]\n", r
->config_file
);
993 printf("\tHelpfile: [%s]\n", r
->help_file
);
995 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
996 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
999 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1000 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1004 /****************************************************************************
1005 ****************************************************************************/
1007 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1015 printf("Printer Driver Info 4:\n");
1016 printf("\tVersion: [%x]\n", r
->version
);
1017 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1018 printf("\tArchitecture: [%s]\n", r
->architecture
);
1019 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1020 printf("\tDatafile: [%s]\n", r
->data_file
);
1021 printf("\tConfigfile: [%s]\n", r
->config_file
);
1022 printf("\tHelpfile: [%s]\n", r
->help_file
);
1024 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1025 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1028 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1029 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1031 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1032 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1037 /****************************************************************************
1038 ****************************************************************************/
1040 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1046 printf("Printer Driver Info 5:\n");
1047 printf("\tVersion: [%x]\n", r
->version
);
1048 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1049 printf("\tArchitecture: [%s]\n", r
->architecture
);
1050 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1051 printf("\tDatafile: [%s]\n", r
->data_file
);
1052 printf("\tConfigfile: [%s]\n", r
->config_file
);
1053 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1054 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1055 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1059 /****************************************************************************
1060 ****************************************************************************/
1062 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1070 printf("Printer Driver Info 6:\n");
1071 printf("\tVersion: [%x]\n", r
->version
);
1072 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1073 printf("\tArchitecture: [%s]\n", r
->architecture
);
1074 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1075 printf("\tDatafile: [%s]\n", r
->data_file
);
1076 printf("\tConfigfile: [%s]\n", r
->config_file
);
1077 printf("\tHelpfile: [%s]\n", r
->help_file
);
1079 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1080 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1083 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1084 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1086 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1087 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1090 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1091 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1092 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1093 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1094 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1095 printf("\tProvider: [%s]\n", r
->provider
);
1100 /****************************************************************************
1101 ****************************************************************************/
1103 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1111 printf("Printer Driver Info 8:\n");
1112 printf("\tVersion: [%x]\n", r
->version
);
1113 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1114 printf("\tArchitecture: [%s]\n", r
->architecture
);
1115 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1116 printf("\tDatafile: [%s]\n", r
->data_file
);
1117 printf("\tConfigfile: [%s]\n", r
->config_file
);
1118 printf("\tHelpfile: [%s]\n", r
->help_file
);
1119 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1120 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1122 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1123 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1126 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1127 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1130 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1131 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1132 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1133 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1134 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1135 printf("\tProvider: [%s]\n", r
->provider
);
1136 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1137 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1138 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1139 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1141 printf("\tInf Path: [%s]\n", r
->inf_path
);
1142 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1143 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1144 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1146 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1147 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1148 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1153 /****************************************************************************
1154 ****************************************************************************/
1156 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1157 TALLOC_CTX
*mem_ctx
,
1158 int argc
, const char **argv
)
1160 struct policy_handle pol
;
1163 const char *printername
;
1165 bool success
= false;
1166 union spoolss_DriverInfo info
;
1167 uint32_t server_major_version
;
1168 uint32_t server_minor_version
;
1170 if ((argc
== 1) || (argc
> 3)) {
1171 printf("Usage: %s <printername> [level]\n", argv
[0]);
1175 /* get the arguments need to open the printer handle */
1177 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1180 level
= atoi(argv
[2]);
1183 /* Open a printer handle */
1185 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1189 if (!W_ERROR_IS_OK(werror
)) {
1190 printf("Error opening printer handle for %s!\n", printername
);
1194 /* loop through and print driver info level for each architecture */
1196 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1198 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1200 archi_table
[i
].long_archi
,
1203 archi_table
[i
].version
,
1206 &server_major_version
,
1207 &server_minor_version
);
1208 if (!W_ERROR_IS_OK(werror
)) {
1212 /* need at least one success */
1216 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1220 display_print_driver1(&info
.info1
);
1223 display_print_driver2(&info
.info2
);
1226 display_print_driver3(&info
.info3
);
1229 display_print_driver4(&info
.info4
);
1232 display_print_driver5(&info
.info5
);
1235 display_print_driver6(&info
.info6
);
1238 display_print_driver8(&info
.info8
);
1241 printf("unknown info level %d\n", level
);
1248 if (is_valid_policy_hnd(&pol
)) {
1249 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1259 /****************************************************************************
1260 ****************************************************************************/
1262 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1263 TALLOC_CTX
*mem_ctx
,
1264 const char *architecture
,
1269 union spoolss_DriverInfo
*info
= NULL
;
1272 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1273 cli
->srv_name_slash
,
1280 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1281 printf("Server does not support environment [%s]\n",
1290 if (!W_ERROR_IS_OK(werror
)) {
1291 printf("Error getting driver for environment [%s] - %s\n",
1292 architecture
, win_errstr(werror
));
1296 printf("\n[%s]\n", architecture
);
1300 for (j
=0; j
< count
; j
++) {
1301 display_print_driver1(&info
[j
].info1
);
1305 for (j
=0; j
< count
; j
++) {
1306 display_print_driver2(&info
[j
].info2
);
1310 for (j
=0; j
< count
; j
++) {
1311 display_print_driver3(&info
[j
].info3
);
1315 for (j
=0; j
< count
; j
++) {
1316 display_print_driver4(&info
[j
].info4
);
1320 for (j
=0; j
< count
; j
++) {
1321 display_print_driver5(&info
[j
].info5
);
1325 for (j
=0; j
< count
; j
++) {
1326 display_print_driver6(&info
[j
].info6
);
1330 for (j
=0; j
< count
; j
++) {
1331 display_print_driver8(&info
[j
].info8
);
1335 printf("unknown info level %d\n", level
);
1336 return WERR_UNKNOWN_LEVEL
;
1342 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1343 TALLOC_CTX
*mem_ctx
,
1344 int argc
, const char **argv
)
1346 WERROR werror
= WERR_OK
;
1349 const char *architecture
= NULL
;
1352 printf("Usage: enumdrivers [level] [architecture]\n");
1357 level
= atoi(argv
[1]);
1361 architecture
= argv
[2];
1365 return enum_driver_by_architecture(cli
, mem_ctx
,
1370 /* loop through and print driver info level for each architecture */
1371 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1372 /* check to see if we already asked for this architecture string */
1374 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1378 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1379 archi_table
[i
].long_archi
,
1381 if (!W_ERROR_IS_OK(werror
)) {
1389 /****************************************************************************
1390 ****************************************************************************/
1392 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1394 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1397 /****************************************************************************
1398 ****************************************************************************/
1400 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1401 TALLOC_CTX
*mem_ctx
,
1402 int argc
, const char **argv
)
1406 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1409 union spoolss_DriverDirectoryInfo info
;
1413 printf("Usage: %s [environment]\n", argv
[0]);
1417 /* Get the arguments need to open the printer handle */
1423 /* Get the directory. Only use Info level 1 */
1425 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1426 cli
->srv_name_slash
,
1434 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1436 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1438 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1439 cli
->srv_name_slash
,
1449 if (W_ERROR_IS_OK(result
)) {
1450 display_printdriverdir_1(&info
.info1
);
1456 /****************************************************************************
1457 ****************************************************************************/
1459 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1460 struct spoolss_AddDriverInfo3
*info
,
1466 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1468 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1470 info
->version
= archi_table
[i
].version
;
1471 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1476 if (archi_table
[i
].long_archi
== NULL
)
1478 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1485 /**************************************************************************
1486 wrapper for strtok to get the next parameter from a delimited list.
1487 Needed to handle the empty parameter string denoted by "NULL"
1488 *************************************************************************/
1490 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1491 const char *delim
, const char **dest
,
1496 /* get the next token */
1497 ptr
= strtok_r(str
, delim
, saveptr
);
1499 /* a string of 'NULL' is used to represent an empty
1500 parameter because two consecutive delimiters
1501 will not return an empty string. See man strtok(3)
1503 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1508 *dest
= talloc_strdup(mem_ctx
, ptr
);
1514 /********************************************************************************
1515 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1516 string in the form of
1517 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1518 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1519 <Default Data Type>:<Comma Separated list of Files>
1520 *******************************************************************************/
1522 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1527 char *saveptr
= NULL
;
1528 struct spoolss_StringArray
*deps
;
1529 const char **file_array
= NULL
;
1532 /* fill in the UNISTR fields */
1533 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1534 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1535 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1536 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1537 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1538 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1539 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1541 /* <Comma Separated List of Dependent Files> */
1542 /* save the beginning of the string */
1543 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1546 /* begin to strip out each filename */
1547 str
= strtok_r(str
, ",", &saveptr
);
1549 /* no dependent files, we are done */
1554 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1559 while (str
!= NULL
) {
1560 add_string_to_array(deps
, str
, &file_array
, &count
);
1561 str
= strtok_r(NULL
, ",", &saveptr
);
1564 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1565 if (!deps
->string
) {
1569 for (i
=0; i
< count
; i
++) {
1570 deps
->string
[i
] = file_array
[i
];
1573 r
->dependent_files
= deps
;
1578 /****************************************************************************
1579 ****************************************************************************/
1581 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1582 TALLOC_CTX
*mem_ctx
,
1583 int argc
, const char **argv
)
1588 struct spoolss_AddDriverInfoCtr info_ctr
;
1589 struct spoolss_AddDriverInfo3 info3
;
1593 /* parse the command arguments */
1594 if (argc
!= 3 && argc
!= 4)
1596 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1597 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1598 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1599 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1600 printf ("\t[version]\n");
1605 /* Fill in the spoolss_AddDriverInfo3 struct */
1608 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1610 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1611 return WERR_INVALID_PARAM
;
1614 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1616 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1617 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1619 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1620 return WERR_INVALID_PARAM
;
1623 /* if printer driver version specified, override the default version
1624 * used by the architecture. This allows installation of Windows
1625 * 2000 (version 3) printer drivers. */
1628 info3
.version
= atoi(argv
[3]);
1632 info_ctr
.level
= level
;
1633 info_ctr
.info
.info3
= &info3
;
1635 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1636 cli
->srv_name_slash
,
1639 if (!NT_STATUS_IS_OK(status
)) {
1640 return ntstatus_to_werror(status
);
1642 if (W_ERROR_IS_OK(result
)) {
1643 printf ("Printer Driver %s successfully installed.\n",
1651 /****************************************************************************
1652 ****************************************************************************/
1654 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1655 TALLOC_CTX
*mem_ctx
,
1656 int argc
, const char **argv
)
1659 struct spoolss_SetPrinterInfoCtr info_ctr
;
1660 struct spoolss_SetPrinterInfo2 info2
;
1662 /* parse the command arguments */
1665 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1669 /* Fill in the DRIVER_INFO_2 struct */
1672 info2
.printername
= argv
[1];
1673 info2
.drivername
= argv
[3];
1674 info2
.sharename
= argv
[2];
1675 info2
.portname
= argv
[4];
1676 info2
.comment
= "Created by rpcclient";
1677 info2
.printprocessor
= "winprint";
1678 info2
.datatype
= "RAW";
1679 info2
.devmode_ptr
= 0;
1680 info2
.secdesc_ptr
= 0;
1681 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1683 info2
.defaultpriority
= 0;
1684 info2
.starttime
= 0;
1685 info2
.untiltime
= 0;
1687 /* These three fields must not be used by AddPrinter()
1688 as defined in the MS Platform SDK documentation..
1692 info2.averageppm = 0;
1696 info_ctr
.info
.info2
= &info2
;
1698 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1700 if (W_ERROR_IS_OK(result
))
1701 printf ("Printer %s successfully installed.\n", argv
[1]);
1706 /****************************************************************************
1707 ****************************************************************************/
1709 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1710 TALLOC_CTX
*mem_ctx
,
1711 int argc
, const char **argv
)
1713 struct policy_handle pol
;
1717 const char *printername
;
1718 union spoolss_PrinterInfo info
;
1719 struct spoolss_SetPrinterInfoCtr info_ctr
;
1720 struct spoolss_DevmodeContainer devmode_ctr
;
1721 struct sec_desc_buf secdesc_ctr
;
1723 ZERO_STRUCT(devmode_ctr
);
1724 ZERO_STRUCT(secdesc_ctr
);
1726 /* parse the command arguments */
1729 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1733 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1735 /* Get a printer handle */
1737 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1741 if (!W_ERROR_IS_OK(result
))
1744 /* Get printer info */
1746 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1751 if (!W_ERROR_IS_OK(result
)) {
1752 printf ("Unable to retrieve printer information!\n");
1756 /* Set the printer driver */
1758 info
.info2
.drivername
= argv
[2];
1759 info
.info2
.devmode
= NULL
;
1760 info
.info2
.secdesc
= NULL
;
1763 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
1765 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1772 if (!W_ERROR_IS_OK(result
)) {
1773 printf("SetPrinter call failed!\n");
1777 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1782 if (is_valid_policy_hnd(&pol
))
1783 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1789 /****************************************************************************
1790 ****************************************************************************/
1792 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1793 TALLOC_CTX
*mem_ctx
,
1794 int argc
, const char **argv
)
1796 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1802 const char *arch
= NULL
;
1803 uint32_t delete_flags
= 0;
1805 /* parse the command arguments */
1806 if (argc
< 2 || argc
> 4) {
1807 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1814 vers
= atoi (argv
[3]);
1817 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1820 /* delete the driver for all architectures */
1821 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1823 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1826 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1829 /* make the call to remove the driver */
1830 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1831 cli
->srv_name_slash
,
1832 archi_table
[i
].long_archi
,
1835 archi_table
[i
].version
,
1838 if ( !W_ERROR_IS_OK(result
) )
1840 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1841 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1842 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1847 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1848 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1857 /****************************************************************************
1858 ****************************************************************************/
1860 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1861 TALLOC_CTX
*mem_ctx
,
1862 int argc
, const char **argv
)
1864 WERROR result
= WERR_OK
;
1868 /* parse the command arguments */
1870 printf ("Usage: %s <driver>\n", argv
[0]);
1874 /* delete the driver for all architectures */
1875 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1876 /* make the call to remove the driver */
1877 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1878 cli
->srv_name_slash
,
1879 archi_table
[i
].long_archi
,
1882 if (!NT_STATUS_IS_OK(status
)) {
1885 if ( !W_ERROR_IS_OK(result
) ) {
1886 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1887 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1888 argv
[1], archi_table
[i
].long_archi
,
1892 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1893 archi_table
[i
].long_archi
);
1900 /****************************************************************************
1901 ****************************************************************************/
1903 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1904 TALLOC_CTX
*mem_ctx
,
1905 int argc
, const char **argv
)
1909 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1912 union spoolss_PrintProcessorDirectoryInfo info
;
1915 /* parse the command arguments */
1917 printf ("Usage: %s [environment]\n", argv
[0]);
1922 environment
= argv
[1];
1925 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1926 cli
->srv_name_slash
,
1934 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1936 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1938 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1939 cli
->srv_name_slash
,
1949 if (W_ERROR_IS_OK(result
)) {
1950 printf("%s\n", info
.info1
.directory_name
);
1956 /****************************************************************************
1957 ****************************************************************************/
1959 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1960 int argc
, const char **argv
)
1962 struct policy_handle handle
;
1965 const char *printername
;
1966 union spoolss_AddFormInfo info
;
1967 struct spoolss_AddFormInfo1 info1
;
1968 struct spoolss_AddFormInfo2 info2
;
1971 /* Parse the command arguments */
1973 if (argc
< 3 || argc
> 5) {
1974 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
1978 /* Get a printer handle */
1980 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1982 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1986 if (!W_ERROR_IS_OK(werror
))
1989 /* Dummy up some values for the form data */
1992 level
= atoi(argv
[3]);
1997 info1
.flags
= SPOOLSS_FORM_USER
;
1998 info1
.form_name
= argv
[2];
1999 info1
.size
.width
= 100;
2000 info1
.size
.height
= 100;
2001 info1
.area
.left
= 0;
2002 info1
.area
.top
= 10;
2003 info1
.area
.right
= 20;
2004 info1
.area
.bottom
= 30;
2006 info
.info1
= &info1
;
2010 info2
.flags
= SPOOLSS_FORM_USER
;
2011 info2
.form_name
= argv
[2];
2012 info2
.size
.width
= 100;
2013 info2
.size
.height
= 100;
2014 info2
.area
.left
= 0;
2015 info2
.area
.top
= 10;
2016 info2
.area
.right
= 20;
2017 info2
.area
.bottom
= 30;
2018 info2
.keyword
= argv
[2];
2019 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2020 info2
.mui_dll
= NULL
;
2021 info2
.ressource_id
= 0;
2022 info2
.display_name
= argv
[2];
2025 info
.info2
= &info2
;
2033 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
2040 if (is_valid_policy_hnd(&handle
))
2041 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2046 /****************************************************************************
2047 ****************************************************************************/
2049 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2050 int argc
, const char **argv
)
2052 struct policy_handle handle
;
2055 const char *printername
;
2056 union spoolss_AddFormInfo info
;
2057 struct spoolss_AddFormInfo1 info1
;
2059 /* Parse the command arguments */
2062 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2066 /* Get a printer handle */
2068 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2070 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2072 SEC_FLAG_MAXIMUM_ALLOWED
,
2074 if (!W_ERROR_IS_OK(werror
))
2077 /* Dummy up some values for the form data */
2079 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2080 info1
.size
.width
= 100;
2081 info1
.size
.height
= 100;
2082 info1
.area
.left
= 0;
2083 info1
.area
.top
= 1000;
2084 info1
.area
.right
= 2000;
2085 info1
.area
.bottom
= 3000;
2086 info1
.form_name
= argv
[2];
2088 info
.info1
= &info1
;
2092 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
2100 if (is_valid_policy_hnd(&handle
))
2101 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2106 /****************************************************************************
2107 ****************************************************************************/
2109 static const char *get_form_flag(int form_flag
)
2111 switch (form_flag
) {
2112 case SPOOLSS_FORM_USER
:
2114 case SPOOLSS_FORM_BUILTIN
:
2115 return "FORM_BUILTIN";
2116 case SPOOLSS_FORM_PRINTER
:
2117 return "FORM_PRINTER";
2123 /****************************************************************************
2124 ****************************************************************************/
2126 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2129 "\tflag: %s (%d)\n" \
2130 "\twidth: %d, length: %d\n" \
2131 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2132 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2133 r
->size
.width
, r
->size
.height
,
2134 r
->area
.left
, r
->area
.right
,
2135 r
->area
.top
, r
->area
.bottom
);
2138 /****************************************************************************
2139 ****************************************************************************/
2141 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2144 "\tflag: %s (%d)\n" \
2145 "\twidth: %d, length: %d\n" \
2146 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2147 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2148 r
->size
.width
, r
->size
.height
,
2149 r
->area
.left
, r
->area
.right
,
2150 r
->area
.top
, r
->area
.bottom
);
2151 printf("\tkeyword: %s\n", r
->keyword
);
2152 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2153 printf("\tmui_dll: %s\n", r
->mui_dll
);
2154 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2155 printf("\tdisplay_name: %s\n", r
->display_name
);
2156 printf("\tlang_id: %d\n", r
->lang_id
);
2160 /****************************************************************************
2161 ****************************************************************************/
2163 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2164 int argc
, const char **argv
)
2166 struct policy_handle handle
;
2169 const char *printername
;
2171 uint32_t offered
= 0;
2172 union spoolss_FormInfo info
;
2176 /* Parse the command arguments */
2178 if (argc
< 3 || argc
> 5) {
2179 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2183 /* Get a printer handle */
2185 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2187 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2189 SEC_FLAG_MAXIMUM_ALLOWED
,
2191 if (!W_ERROR_IS_OK(werror
))
2195 level
= atoi(argv
[3]);
2200 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2209 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2210 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2212 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2223 if (!NT_STATUS_IS_OK(status
)) {
2229 display_form_info1(&info
.info1
);
2232 display_form_info2(&info
.info2
);
2237 if (is_valid_policy_hnd(&handle
))
2238 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2243 /****************************************************************************
2244 ****************************************************************************/
2246 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2247 TALLOC_CTX
*mem_ctx
, int argc
,
2250 struct policy_handle handle
;
2253 const char *printername
;
2255 /* Parse the command arguments */
2258 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2262 /* Get a printer handle */
2264 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2266 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2268 SEC_FLAG_MAXIMUM_ALLOWED
,
2270 if (!W_ERROR_IS_OK(werror
))
2273 /* Delete the form */
2275 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2279 if (!NT_STATUS_IS_OK(status
)) {
2280 return ntstatus_to_werror(status
);
2284 if (is_valid_policy_hnd(&handle
))
2285 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2290 /****************************************************************************
2291 ****************************************************************************/
2293 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2294 TALLOC_CTX
*mem_ctx
, int argc
,
2297 struct policy_handle handle
;
2299 const char *printername
;
2300 uint32_t num_forms
, level
= 1, i
;
2301 union spoolss_FormInfo
*forms
;
2303 /* Parse the command arguments */
2305 if (argc
< 2 || argc
> 4) {
2306 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2310 /* Get a printer handle */
2312 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2314 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2316 SEC_FLAG_MAXIMUM_ALLOWED
,
2318 if (!W_ERROR_IS_OK(werror
))
2322 level
= atoi(argv
[2]);
2325 /* Enumerate forms */
2327 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2334 if (!W_ERROR_IS_OK(werror
))
2337 /* Display output */
2339 for (i
= 0; i
< num_forms
; i
++) {
2342 display_form_info1(&forms
[i
].info1
);
2345 display_form_info2(&forms
[i
].info2
);
2351 if (is_valid_policy_hnd(&handle
))
2352 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2357 /****************************************************************************
2358 ****************************************************************************/
2360 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2361 TALLOC_CTX
*mem_ctx
,
2362 int argc
, const char **argv
)
2366 const char *printername
;
2367 struct policy_handle pol
;
2368 union spoolss_PrinterInfo info
;
2369 enum winreg_Type type
;
2370 union spoolss_PrinterData data
;
2373 /* parse the command arguments */
2375 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2376 " <value> <data>\n",
2378 result
= WERR_INVALID_PARAM
;
2382 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2386 if (strequal(argv
[2], "string")) {
2390 if (strequal(argv
[2], "binary")) {
2394 if (strequal(argv
[2], "dword")) {
2398 if (strequal(argv
[2], "multistring")) {
2399 type
= REG_MULTI_SZ
;
2402 if (type
== REG_NONE
) {
2403 printf("Unknown data type: %s\n", argv
[2]);
2404 result
= WERR_INVALID_PARAM
;
2408 /* get a printer handle */
2410 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2412 SEC_FLAG_MAXIMUM_ALLOWED
,
2414 if (!W_ERROR_IS_OK(result
)) {
2418 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2423 if (!W_ERROR_IS_OK(result
)) {
2427 printf("%s\n", current_timestring(mem_ctx
, true));
2428 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2430 /* Set the printer data */
2434 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2435 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2438 data
.value
= strtoul(argv
[4], NULL
, 10);
2441 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2443 case REG_MULTI_SZ
: {
2445 const char **strings
= NULL
;
2447 for (i
=4; i
<argc
; i
++) {
2448 if (strcmp(argv
[i
], "NULL") == 0) {
2451 if (!add_string_to_array(mem_ctx
, argv
[i
],
2454 result
= WERR_NOMEM
;
2458 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2459 if (!data
.string_array
) {
2460 result
= WERR_NOMEM
;
2463 for (i
=0; i
< num_strings
; i
++) {
2464 data
.string_array
[i
] = strings
[i
];
2469 printf("Unknown data type: %s\n", argv
[2]);
2470 result
= WERR_INVALID_PARAM
;
2474 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2475 if (!W_ERROR_IS_OK(result
)) {
2479 status
= rpccli_spoolss_SetPrinterData(cli
, mem_ctx
,
2481 argv
[3], /* value_name */
2486 if (!W_ERROR_IS_OK(result
)) {
2487 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2490 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2492 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2497 if (!W_ERROR_IS_OK(result
)) {
2501 printf("%s\n", current_timestring(mem_ctx
, true));
2502 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2506 if (is_valid_policy_hnd(&pol
)) {
2507 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2513 /****************************************************************************
2514 ****************************************************************************/
2516 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2518 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2519 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2523 /****************************************************************************
2524 ****************************************************************************/
2526 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2528 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2529 r
->position
, r
->job_id
,
2530 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2531 r
->total_pages
, r
->size
);
2534 /****************************************************************************
2535 ****************************************************************************/
2537 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2539 printf("jobid[%d], next_jobid[%d]\n",
2540 r
->job_id
, r
->next_job_id
);
2543 /****************************************************************************
2544 ****************************************************************************/
2546 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2548 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2549 r
->position
, r
->job_id
,
2550 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2551 r
->total_pages
, r
->size
, r
->size_high
);
2554 /****************************************************************************
2555 ****************************************************************************/
2557 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2558 TALLOC_CTX
*mem_ctx
, int argc
,
2562 uint32_t level
= 1, count
, i
;
2563 const char *printername
;
2564 struct policy_handle hnd
;
2565 union spoolss_JobInfo
*info
;
2567 if (argc
< 2 || argc
> 3) {
2568 printf("Usage: %s printername [level]\n", argv
[0]);
2573 level
= atoi(argv
[2]);
2576 /* Open printer handle */
2578 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2580 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2582 SEC_FLAG_MAXIMUM_ALLOWED
,
2584 if (!W_ERROR_IS_OK(result
))
2587 /* Enumerate ports */
2589 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2597 if (!W_ERROR_IS_OK(result
)) {
2601 for (i
= 0; i
< count
; i
++) {
2604 display_job_info1(&info
[i
].info1
);
2607 display_job_info2(&info
[i
].info2
);
2610 d_printf("unknown info level %d\n", level
);
2616 if (is_valid_policy_hnd(&hnd
)) {
2617 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2623 /****************************************************************************
2624 ****************************************************************************/
2626 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2627 TALLOC_CTX
*mem_ctx
, int argc
,
2631 const char *printername
;
2632 struct policy_handle hnd
;
2635 union spoolss_JobInfo info
;
2637 if (argc
< 3 || argc
> 4) {
2638 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2642 job_id
= atoi(argv
[2]);
2645 level
= atoi(argv
[3]);
2648 /* Open printer handle */
2650 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2652 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2654 SEC_FLAG_MAXIMUM_ALLOWED
,
2656 if (!W_ERROR_IS_OK(result
)) {
2660 /* Enumerate ports */
2662 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2669 if (!W_ERROR_IS_OK(result
)) {
2675 display_job_info1(&info
.info1
);
2678 display_job_info2(&info
.info2
);
2681 display_job_info3(&info
.info3
);
2684 display_job_info4(&info
.info4
);
2687 d_printf("unknown info level %d\n", level
);
2692 if (is_valid_policy_hnd(&hnd
)) {
2693 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2699 /****************************************************************************
2700 ****************************************************************************/
2702 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2703 TALLOC_CTX
*mem_ctx
, int argc
,
2708 const char *printername
;
2709 struct policy_handle hnd
;
2711 enum spoolss_JobControl command
;
2714 printf("Usage: %s printername job_id command\n", argv
[0]);
2718 job_id
= atoi(argv
[2]);
2719 command
= atoi(argv
[3]);
2721 /* Open printer handle */
2723 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2725 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2727 SEC_FLAG_MAXIMUM_ALLOWED
,
2729 if (!W_ERROR_IS_OK(result
)) {
2735 status
= rpccli_spoolss_SetJob(cli
, mem_ctx
,
2742 if (!W_ERROR_IS_OK(result
)) {
2747 if (is_valid_policy_hnd(&hnd
)) {
2748 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2754 /****************************************************************************
2755 ****************************************************************************/
2757 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2758 TALLOC_CTX
*mem_ctx
, int argc
,
2764 const char *printername
;
2765 struct policy_handle hnd
;
2766 uint32_t value_offered
= 0;
2767 const char *value_name
= NULL
;
2768 uint32_t value_needed
;
2769 enum winreg_Type type
;
2770 uint8_t *data
= NULL
;
2771 uint32_t data_offered
= 0;
2772 uint32_t data_needed
;
2775 printf("Usage: %s printername\n", argv
[0]);
2779 /* Open printer handle */
2781 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2783 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2785 SEC_FLAG_MAXIMUM_ALLOWED
,
2787 if (!W_ERROR_IS_OK(result
)) {
2791 /* Enumerate data */
2793 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2805 data_offered
= data_needed
;
2806 value_offered
= value_needed
;
2807 data
= talloc_zero_array(mem_ctx
, uint8_t, data_needed
);
2808 value_name
= talloc_zero_array(mem_ctx
, char, value_needed
);
2810 while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2812 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2823 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2824 struct regval_blob v
;
2825 fstrcpy(v
.valuename
, value_name
);
2827 v
.size
= data_offered
;
2829 display_reg_value(v
);
2833 if (W_ERROR_V(result
) == ERRnomoreitems
) {
2834 result
= W_ERROR(ERRsuccess
);
2838 if (is_valid_policy_hnd(&hnd
)) {
2839 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2845 /****************************************************************************
2846 ****************************************************************************/
2848 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2849 TALLOC_CTX
*mem_ctx
, int argc
,
2854 const char *printername
;
2855 struct policy_handle hnd
;
2857 struct spoolss_PrinterEnumValues
*info
;
2860 printf("Usage: %s printername <keyname>\n", argv
[0]);
2864 /* Open printer handle */
2866 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2868 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2870 SEC_FLAG_MAXIMUM_ALLOWED
,
2872 if (!W_ERROR_IS_OK(result
)) {
2876 /* Enumerate subkeys */
2878 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
2884 if (!W_ERROR_IS_OK(result
)) {
2888 for (i
=0; i
< count
; i
++) {
2889 display_printer_data(info
[i
].value_name
,
2895 if (is_valid_policy_hnd(&hnd
)) {
2896 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2902 /****************************************************************************
2903 ****************************************************************************/
2905 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
2906 TALLOC_CTX
*mem_ctx
, int argc
,
2910 const char *printername
;
2911 const char *keyname
= NULL
;
2912 struct policy_handle hnd
;
2913 const char **key_buffer
= NULL
;
2915 uint32_t offered
= 0;
2917 if (argc
< 2 || argc
> 4) {
2918 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
2929 offered
= atoi(argv
[3]);
2932 /* Open printer handle */
2934 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2936 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2938 SEC_FLAG_MAXIMUM_ALLOWED
,
2940 if (!W_ERROR_IS_OK(result
)) {
2944 /* Enumerate subkeys */
2946 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
2952 if (!W_ERROR_IS_OK(result
)) {
2956 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
2957 printf("%s\n", key_buffer
[i
]);
2962 if (is_valid_policy_hnd(&hnd
)) {
2963 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2969 /****************************************************************************
2970 ****************************************************************************/
2972 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2973 TALLOC_CTX
*mem_ctx
, int argc
,
2976 const char *printername
;
2977 const char *clientname
;
2978 struct policy_handle hnd
;
2981 struct spoolss_NotifyOption option
;
2984 printf("Usage: %s printername\n", argv
[0]);
2991 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2993 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2995 SEC_FLAG_MAXIMUM_ALLOWED
,
2997 if (!W_ERROR_IS_OK(result
)) {
2998 printf("Error opening %s\n", argv
[1]);
3002 /* Create spool options */
3007 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3008 if (option
.types
== NULL
) {
3009 result
= WERR_NOMEM
;
3013 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3014 option
.types
[0].count
= 1;
3015 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3016 if (option
.types
[0].fields
== NULL
) {
3017 result
= WERR_NOMEM
;
3020 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3022 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3023 option
.types
[1].count
= 1;
3024 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3025 if (option
.types
[1].fields
== NULL
) {
3026 result
= WERR_NOMEM
;
3029 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3031 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
3033 result
= WERR_NOMEM
;
3039 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
3047 if (!W_ERROR_IS_OK(result
)) {
3048 printf("Error rffpcnex %s\n", argv
[1]);
3053 if (is_valid_policy_hnd(&hnd
))
3054 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3059 /****************************************************************************
3060 ****************************************************************************/
3062 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3063 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3065 union spoolss_PrinterInfo info1
, info2
;
3067 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3069 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3070 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3075 if ( !W_ERROR_IS_OK(werror
) ) {
3076 printf("failed (%s)\n", win_errstr(werror
));
3077 talloc_destroy(mem_ctx
);
3082 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3083 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3088 if ( !W_ERROR_IS_OK(werror
) ) {
3089 printf("failed (%s)\n", win_errstr(werror
));
3090 talloc_destroy(mem_ctx
);
3095 talloc_destroy(mem_ctx
);
3100 /****************************************************************************
3101 ****************************************************************************/
3103 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3104 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3106 union spoolss_PrinterInfo info1
, info2
;
3108 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3109 SEC_DESC
*sd1
, *sd2
;
3113 printf("Retrieving printer security for %s...", cli1
->desthost
);
3114 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3119 if ( !W_ERROR_IS_OK(werror
) ) {
3120 printf("failed (%s)\n", win_errstr(werror
));
3126 printf("Retrieving printer security for %s...", cli2
->desthost
);
3127 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3132 if ( !W_ERROR_IS_OK(werror
) ) {
3133 printf("failed (%s)\n", win_errstr(werror
));
3142 sd1
= info1
.info3
.secdesc
;
3143 sd2
= info2
.info3
.secdesc
;
3145 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3146 printf("NULL secdesc!\n");
3151 if (!security_descriptor_equal( sd1
, sd2
) ) {
3152 printf("Security Descriptors *not* equal!\n");
3157 printf("Security descriptors match\n");
3160 talloc_destroy(mem_ctx
);
3165 /****************************************************************************
3166 ****************************************************************************/
3168 extern struct user_auth_info
*rpcclient_auth_info
;
3170 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3171 TALLOC_CTX
*mem_ctx
, int argc
,
3174 const char *printername
;
3175 char *printername_path
= NULL
;
3176 struct cli_state
*cli_server2
= NULL
;
3177 struct rpc_pipe_client
*cli2
= NULL
;
3178 struct policy_handle hPrinter1
, hPrinter2
;
3183 printf("Usage: %s <printer> <server>\n", argv
[0]);
3187 printername
= argv
[1];
3189 /* first get the connection to the remote server */
3191 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
3194 get_cmdline_auth_info_username(rpcclient_auth_info
),
3196 get_cmdline_auth_info_password(rpcclient_auth_info
),
3197 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3198 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
3200 if ( !NT_STATUS_IS_OK(nt_status
) )
3201 return WERR_GENERAL_FAILURE
;
3203 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
.syntax_id
,
3205 if (!NT_STATUS_IS_OK(nt_status
)) {
3206 printf("failed to open spoolss pipe on server %s (%s)\n",
3207 argv
[2], nt_errstr(nt_status
));
3208 return WERR_GENERAL_FAILURE
;
3211 /* now open up both printers */
3213 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3215 printf("Opening %s...", printername_path
);
3217 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3221 if ( !W_ERROR_IS_OK(werror
) ) {
3222 printf("failed (%s)\n", win_errstr(werror
));
3227 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3229 printf("Opening %s...", printername_path
);
3230 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3234 if ( !W_ERROR_IS_OK(werror
) ) {
3235 printf("failed (%s)\n", win_errstr(werror
));
3240 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3241 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3243 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3250 printf("Closing printers...");
3251 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3252 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3255 /* close the second remote connection */
3257 cli_shutdown( cli_server2
);
3261 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3263 printf("print_processor_name: %s\n", r
->print_processor_name
);
3266 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3267 TALLOC_CTX
*mem_ctx
, int argc
,
3271 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3272 uint32_t num_procs
, level
= 1, i
;
3273 union spoolss_PrintProcessorInfo
*procs
;
3275 /* Parse the command arguments */
3277 if (argc
< 1 || argc
> 4) {
3278 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3283 environment
= argv
[1];
3287 level
= atoi(argv
[2]);
3290 /* Enumerate Print Processors */
3292 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3293 cli
->srv_name_slash
,
3299 if (!W_ERROR_IS_OK(werror
))
3302 /* Display output */
3304 for (i
= 0; i
< num_procs
; i
++) {
3307 display_proc_info1(&procs
[i
].info1
);
3316 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3318 printf("name_array: %s\n", r
->name_array
);
3321 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3322 TALLOC_CTX
*mem_ctx
, int argc
,
3326 const char *print_processor_name
= "winprint";
3327 uint32_t num_procs
, level
= 1, i
;
3328 union spoolss_PrintProcDataTypesInfo
*procs
;
3330 /* Parse the command arguments */
3332 if (argc
< 1 || argc
> 4) {
3333 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3338 print_processor_name
= argv
[1];
3342 level
= atoi(argv
[2]);
3345 /* Enumerate Print Processor Data Types */
3347 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3348 cli
->srv_name_slash
,
3349 print_processor_name
,
3354 if (!W_ERROR_IS_OK(werror
))
3357 /* Display output */
3359 for (i
= 0; i
< num_procs
; i
++) {
3362 display_proc_data_types_info1(&procs
[i
].info1
);
3371 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3373 printf("monitor_name: %s\n", r
->monitor_name
);
3376 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3378 printf("monitor_name: %s\n", r
->monitor_name
);
3379 printf("environment: %s\n", r
->environment
);
3380 printf("dll_name: %s\n", r
->dll_name
);
3383 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3384 TALLOC_CTX
*mem_ctx
, int argc
,
3388 uint32_t count
, level
= 1, i
;
3389 union spoolss_MonitorInfo
*info
;
3391 /* Parse the command arguments */
3394 printf("Usage: %s [level]\n", argv
[0]);
3399 level
= atoi(argv
[1]);
3402 /* Enumerate Print Monitors */
3404 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3405 cli
->srv_name_slash
,
3410 if (!W_ERROR_IS_OK(werror
)) {
3414 /* Display output */
3416 for (i
= 0; i
< count
; i
++) {
3419 display_monitor1(&info
[i
].info1
);
3422 display_monitor2(&info
[i
].info2
);
3431 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3432 TALLOC_CTX
*mem_ctx
, int argc
,
3437 struct policy_handle handle
, gdi_handle
;
3438 const char *printername
;
3439 struct spoolss_DevmodeContainer devmode_ctr
;
3441 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3443 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3445 SEC_FLAG_MAXIMUM_ALLOWED
,
3447 if (!W_ERROR_IS_OK(result
)) {
3451 ZERO_STRUCT(devmode_ctr
);
3453 status
= rpccli_spoolss_CreatePrinterIC(cli
, mem_ctx
,
3458 if (!W_ERROR_IS_OK(result
)) {
3463 if (is_valid_policy_hnd(&gdi_handle
)) {
3464 rpccli_spoolss_DeletePrinterIC(cli
, mem_ctx
, &gdi_handle
, NULL
);
3466 if (is_valid_policy_hnd(&handle
)) {
3467 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
3473 /* List of commands exported by this module */
3474 struct cmd_set spoolss_commands
[] = {
3478 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a print driver", "" },
3479 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a printer", "" },
3480 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver", "" },
3481 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver with files", "" },
3482 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data", "" },
3483 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data for a key", "" },
3484 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer keys", "" },
3485 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate print jobs", "" },
3486 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print job", "" },
3487 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set print job", "" },
3488 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer ports", "" },
3489 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate installed printer drivers", "" },
3490 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printers", "" },
3491 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver data", "" },
3492 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer driver data with keyname", ""},
3493 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver information", "" },
3494 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver upload directory", "" },
3495 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer info", "" },
3496 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3497 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer driver", "" },
3498 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print processor directory", "" },
3499 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add form", "" },
3500 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set form", "" },
3501 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get form", "" },
3502 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete form", "" },
3503 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate forms", "" },
3504 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer comment", "" },
3505 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printername", "" },
3506 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set REG_SZ printer data", "" },
3507 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Rffpcnex test", "" },
3508 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
.syntax_id
, NULL
, "Printer comparison test", "" },
3509 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processors", "" },
3510 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processor Data Types", "" },
3511 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Monitors", "" },
3512 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
.syntax_id
, NULL
, "Create Printer IC", "" },