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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpcclient.h"
27 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
29 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
30 _cli->srv_name_slash, _arg); \
31 W_ERROR_HAVE_NO_MEMORY(_printername); \
35 const char *long_archi
;
36 const char *short_archi
;
40 /* The version int is used by getdrivers. Note that
41 all architecture strings that support mutliple
42 versions must be grouped together since enumdrivers
43 uses this property to prevent issuing multiple
44 enumdriver calls for the same arch */
47 static const struct table_node archi_table
[]= {
49 {"Windows 4.0", "WIN40", 0 },
50 {"Windows NT x86", "W32X86", 2 },
51 {"Windows NT x86", "W32X86", 3 },
52 {"Windows NT R4000", "W32MIPS", 2 },
53 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
54 {"Windows NT PowerPC", "W32PPC", 2 },
55 {"Windows IA64", "IA64", 3 },
56 {"Windows x64", "x64", 3 },
63 * rpcclient module for SPOOLSS rpc pipe.
65 * This generally just parses and checks command lines, and then calls
66 * a cli_spoolss function.
69 /****************************************************************************
70 function to do the mapping between the long architecture name and
72 ****************************************************************************/
74 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
78 DEBUG(107,("Getting architecture dependant directory\n"));
81 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
82 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
84 if (archi_table
[i
].long_archi
==NULL
) {
85 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
89 /* this might be client code - but shouldn't this be an fstrcpy etc? */
92 DEBUGADD(108,("index: [%d]\n", i
));
93 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
94 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
96 return archi_table
[i
].short_archi
;
99 /****************************************************************************
100 ****************************************************************************/
102 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
104 int argc
, const char **argv
)
110 printf("Usage: %s <printername>\n", argv
[0]);
115 return WERR_GENERAL_FAILURE
;
117 /* Open the printer handle */
119 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
123 if (W_ERROR_IS_OK(werror
)) {
124 printf("Printer %s opened successfully\n", argv
[1]);
125 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
127 if (!W_ERROR_IS_OK(werror
)) {
128 printf("Error closing printer handle! (%s)\n",
129 get_dos_error_msg(werror
));
137 /****************************************************************************
138 ****************************************************************************/
140 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
145 printf("\tprintername:[%s]\n", r
->printername
);
146 printf("\tservername:[%s]\n", r
->servername
);
147 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
148 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
149 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
150 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
151 r
->time
.day
, r
->time
.day_of_week
);
152 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
153 r
->time
.second
, r
->time
.millisecond
);
155 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
156 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
158 printf("\tversion:[0x%x]\n", r
->version
);
159 printf("\tfree_build:[0x%x]\n", r
->free_build
);
160 printf("\tspooling:[0x%x]\n", r
->spooling
);
161 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
162 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
163 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
164 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
165 printf("\tjob_error:[0x%x]\n", r
->job_error
);
166 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
167 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
168 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
169 printf("\tchange_id:[0x%x]\n", r
->change_id
);
170 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
171 printf("\tstatus:[0x%x]\n", r
->status
);
172 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
173 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
174 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
175 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
176 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
177 printf("\treserved2:[0x%x]\n", r
->reserved2
);
178 printf("\treserved3:[0x%x]\n", r
->reserved3
);
183 /****************************************************************************
184 ****************************************************************************/
186 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
188 printf("\tflags:[0x%x]\n", r
->flags
);
189 printf("\tname:[%s]\n", r
->name
);
190 printf("\tdescription:[%s]\n", r
->description
);
191 printf("\tcomment:[%s]\n", r
->comment
);
196 /****************************************************************************
197 ****************************************************************************/
199 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
201 printf("\tservername:[%s]\n", r
->servername
);
202 printf("\tprintername:[%s]\n", r
->printername
);
203 printf("\tsharename:[%s]\n", r
->sharename
);
204 printf("\tportname:[%s]\n", r
->portname
);
205 printf("\tdrivername:[%s]\n", r
->drivername
);
206 printf("\tcomment:[%s]\n", r
->comment
);
207 printf("\tlocation:[%s]\n", r
->location
);
208 printf("\tsepfile:[%s]\n", r
->sepfile
);
209 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
210 printf("\tdatatype:[%s]\n", r
->datatype
);
211 printf("\tparameters:[%s]\n", r
->parameters
);
212 printf("\tattributes:[0x%x]\n", r
->attributes
);
213 printf("\tpriority:[0x%x]\n", r
->priority
);
214 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
215 printf("\tstarttime:[0x%x]\n", r
->starttime
);
216 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
217 printf("\tstatus:[0x%x]\n", r
->status
);
218 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
219 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
222 display_sec_desc(r
->secdesc
);
227 /****************************************************************************
228 ****************************************************************************/
230 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
232 display_sec_desc(r
->secdesc
);
237 /****************************************************************************
238 ****************************************************************************/
240 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
242 printf("\tguid:[%s]\n", r
->guid
);
243 printf("\taction:[0x%x]\n", r
->action
);
247 /****************************************************************************
248 ****************************************************************************/
250 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
252 int argc
, const char **argv
)
256 union spoolss_PrinterInfo
*info
;
261 printf("Usage: %s [level] [name]\n", argv
[0]);
266 level
= atoi(argv
[1]);
272 name
= cli
->srv_name_slash
;
275 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
282 if (W_ERROR_IS_OK(result
)) {
285 printf ("No printers returned.\n");
289 for (i
= 0; i
< count
; i
++) {
292 display_print_info0(&info
[i
].info0
);
295 display_print_info1(&info
[i
].info1
);
298 display_print_info2(&info
[i
].info2
);
301 display_print_info3(&info
[i
].info3
);
304 printf("unknown info level %d\n", level
);
314 /****************************************************************************
315 ****************************************************************************/
317 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
319 printf("\tPort Name:\t[%s]\n", r
->port_name
);
322 /****************************************************************************
323 ****************************************************************************/
325 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
327 printf("\tPort Name:\t[%s]\n", r
->port_name
);
328 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
329 printf("\tDescription:\t[%s]\n", r
->description
);
330 printf("\tPort Type:\t" );
332 int comma
= 0; /* hack */
334 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
338 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
339 printf( "%sWrite", comma
? ", " : "" );
342 /* These two have slightly different interpretations
343 on 95/98/ME but I'm disregarding that for now */
344 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
345 printf( "%sRedirected", comma
? ", " : "" );
348 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
349 printf( "%sNet-Attached", comma
? ", " : "" );
353 printf( "[Unset]\n" );
355 printf("\tReserved:\t[%d]\n", r
->reserved
);
359 /****************************************************************************
360 ****************************************************************************/
362 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
363 TALLOC_CTX
*mem_ctx
, int argc
,
369 union spoolss_PortInfo
*info
;
372 printf("Usage: %s [level]\n", argv
[0]);
377 level
= atoi(argv
[1]);
380 /* Enumerate ports */
382 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
388 if (W_ERROR_IS_OK(result
)) {
391 for (i
= 0; i
< count
; i
++) {
394 display_port_info_1(&info
[i
].info1
);
397 display_port_info_2(&info
[i
].info2
);
400 printf("unknown info level %d\n", level
);
409 /****************************************************************************
410 ****************************************************************************/
412 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
414 int argc
, const char **argv
)
419 uint32 info_level
= 2;
420 union spoolss_PrinterInfo info
;
421 struct spoolss_SetPrinterInfoCtr info_ctr
;
422 const char *printername
, *comment
= NULL
;
423 struct spoolss_DevmodeContainer devmode_ctr
;
424 struct sec_desc_buf secdesc_ctr
;
426 if (argc
== 1 || argc
> 3) {
427 printf("Usage: %s printername comment\n", argv
[0]);
432 /* Open a printer handle */
437 ZERO_STRUCT(devmode_ctr
);
438 ZERO_STRUCT(secdesc_ctr
);
440 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
442 /* get a printer handle */
443 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
447 if (!W_ERROR_IS_OK(result
))
450 /* Get printer info */
451 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
456 if (!W_ERROR_IS_OK(result
))
460 /* Modify the comment. */
461 info
.info2
.comment
= comment
;
462 info
.info2
.secdesc
= NULL
;
463 info
.info2
.devmode
= NULL
;
466 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
468 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
475 if (W_ERROR_IS_OK(result
))
476 printf("Success in setting comment.\n");
479 if (is_valid_policy_hnd(&pol
))
480 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
485 /****************************************************************************
486 ****************************************************************************/
488 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
490 int argc
, const char **argv
)
495 uint32 info_level
= 2;
496 union spoolss_PrinterInfo info
;
497 const char *printername
,
498 *new_printername
= NULL
;
499 struct spoolss_SetPrinterInfoCtr info_ctr
;
500 struct spoolss_DevmodeContainer devmode_ctr
;
501 struct sec_desc_buf secdesc_ctr
;
503 ZERO_STRUCT(devmode_ctr
);
504 ZERO_STRUCT(secdesc_ctr
);
506 if (argc
== 1 || argc
> 3) {
507 printf("Usage: %s printername new_printername\n", argv
[0]);
512 /* Open a printer handle */
514 new_printername
= argv
[2];
517 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
519 /* get a printer handle */
520 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
524 if (!W_ERROR_IS_OK(result
))
527 /* Get printer info */
528 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
533 if (!W_ERROR_IS_OK(result
))
536 /* Modify the printername. */
537 info
.info2
.printername
= new_printername
;
538 info
.info2
.devmode
= NULL
;
539 info
.info2
.secdesc
= NULL
;
541 info_ctr
.level
= info_level
;
542 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
544 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
551 if (W_ERROR_IS_OK(result
))
552 printf("Success in setting printername.\n");
555 if (is_valid_policy_hnd(&pol
))
556 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
561 /****************************************************************************
562 ****************************************************************************/
564 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
566 int argc
, const char **argv
)
570 uint32 info_level
= 1;
571 const char *printername
;
572 union spoolss_PrinterInfo info
;
574 if (argc
== 1 || argc
> 3) {
575 printf("Usage: %s <printername> [level]\n", argv
[0]);
579 /* Open a printer handle */
581 info_level
= atoi(argv
[2]);
584 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
586 /* get a printer handle */
588 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
590 SEC_FLAG_MAXIMUM_ALLOWED
,
592 if (!W_ERROR_IS_OK(result
))
595 /* Get printer info */
597 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
602 if (!W_ERROR_IS_OK(result
))
605 /* Display printer info */
606 switch (info_level
) {
608 display_print_info0(&info
.info0
);
611 display_print_info1(&info
.info1
);
614 display_print_info2(&info
.info2
);
617 display_print_info3(&info
.info3
);
620 display_print_info7(&info
.info7
);
623 printf("unknown info level %d\n", info_level
);
627 if (is_valid_policy_hnd(&pol
))
628 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
633 /****************************************************************************
634 ****************************************************************************/
636 static void display_reg_value(REGISTRY_VALUE value
)
642 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
643 *((uint32
*) value
.data_p
));
646 rpcstr_pull_talloc(talloc_tos(),
651 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
654 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
656 printf("%s: REG_BINARY:", value
.valuename
);
658 for (i
=0; i
<len
; i
++) {
659 if (hex
[i
] == '\0') {
672 uint32 i
, num_values
;
675 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL
, value
.data_p
,
676 value
.size
, &num_values
,
678 d_printf("reg_pull_multi_sz failed\n");
682 for (i
=0; i
<num_values
; i
++) {
683 d_printf("%s\n", values
[i
]);
689 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
694 /****************************************************************************
695 ****************************************************************************/
697 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
699 int argc
, const char **argv
)
704 const char *valuename
;
705 REGISTRY_VALUE value
;
708 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
709 printf("<printername> of . queries print server\n");
714 /* Open a printer handle */
716 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
717 fstrcpy(printername
, cli
->srv_name_slash
);
719 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
720 cli
->srv_name_slash
, argv
[1]);
722 /* get a printer handle */
724 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
726 SEC_FLAG_MAXIMUM_ALLOWED
,
728 if (!W_ERROR_IS_OK(result
))
731 /* Get printer info */
733 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
735 if (!W_ERROR_IS_OK(result
))
738 /* Display printer data */
740 fstrcpy(value
.valuename
, valuename
);
741 display_reg_value(value
);
745 if (is_valid_policy_hnd(&pol
))
746 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
751 /****************************************************************************
752 ****************************************************************************/
754 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
756 int argc
, const char **argv
)
762 const char *valuename
, *keyname
;
763 REGISTRY_VALUE value
;
766 uint8_t *buffer
= NULL
;
767 uint32_t offered
= 0;
771 printf("Usage: %s <printername> <keyname> <valuename>\n",
773 printf("<printername> of . queries print server\n");
779 /* Open a printer handle */
781 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
782 fstrcpy(printername
, cli
->srv_name_slash
);
784 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
785 cli
->srv_name_slash
, argv
[1]);
787 /* get a printer handle */
789 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
791 SEC_FLAG_MAXIMUM_ALLOWED
,
793 if (!W_ERROR_IS_OK(result
))
796 /* Get printer info */
798 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
807 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
809 buffer
= talloc_array(mem_ctx
, uint8_t, needed
);
810 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
821 if (!NT_STATUS_IS_OK(status
)) {
825 if (!W_ERROR_IS_OK(result
)) {
830 if (!W_ERROR_IS_OK(result
))
833 /* Display printer data */
835 fstrcpy(value
.valuename
, valuename
);
838 value
.data_p
= buffer
;
840 display_reg_value(value
);
843 if (is_valid_policy_hnd(&pol
))
844 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
849 /****************************************************************************
850 ****************************************************************************/
852 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
858 printf("Printer Driver Info 1:\n");
859 printf("\tDriver Name: [%s]\n\n", r
->driver_name
);
862 /****************************************************************************
863 ****************************************************************************/
865 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
871 printf("Printer Driver Info 2:\n");
872 printf("\tVersion: [%x]\n", r
->version
);
873 printf("\tDriver Name: [%s]\n", r
->driver_name
);
874 printf("\tArchitecture: [%s]\n", r
->architecture
);
875 printf("\tDriver Path: [%s]\n", r
->driver_path
);
876 printf("\tDatafile: [%s]\n", r
->data_file
);
877 printf("\tConfigfile: [%s]\n\n", r
->config_file
);
880 /****************************************************************************
881 ****************************************************************************/
883 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
891 printf("Printer Driver Info 3:\n");
892 printf("\tVersion: [%x]\n", r
->version
);
893 printf("\tDriver Name: [%s]\n", r
->driver_name
);
894 printf("\tArchitecture: [%s]\n", r
->architecture
);
895 printf("\tDriver Path: [%s]\n", r
->driver_path
);
896 printf("\tDatafile: [%s]\n", r
->data_file
);
897 printf("\tConfigfile: [%s]\n\n", r
->config_file
);
898 printf("\tHelpfile: [%s]\n\n", r
->help_file
);
900 for (i
=0; r
->dependent_files
[i
] != NULL
; i
++) {
901 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
906 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
907 printf("\tDefaultdatatype: [%s]\n\n", r
->default_datatype
);
911 /****************************************************************************
912 ****************************************************************************/
914 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
916 int argc
, const char **argv
)
920 uint32 info_level
= 3;
921 const char *printername
;
923 bool success
= False
;
924 union spoolss_DriverInfo info
;
925 uint32_t server_major_version
;
926 uint32_t server_minor_version
;
928 if ((argc
== 1) || (argc
> 3))
930 printf("Usage: %s <printername> [level]\n", argv
[0]);
934 /* get the arguments need to open the printer handle */
936 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
939 info_level
= atoi(argv
[2]);
941 /* Open a printer handle */
943 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
947 if (!W_ERROR_IS_OK(werror
)) {
948 printf("Error opening printer handle for %s!\n", printername
);
952 /* loop through and print driver info level for each architecture */
954 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
956 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
958 archi_table
[i
].long_archi
,
961 archi_table
[i
].version
,
964 &server_major_version
,
965 &server_minor_version
);
966 if (!W_ERROR_IS_OK(werror
))
969 /* need at least one success */
973 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
975 switch (info_level
) {
977 display_print_driver1(&info
.info1
);
980 display_print_driver2(&info
.info2
);
983 display_print_driver3(&info
.info3
);
986 printf("unknown info level %d\n", info_level
);
993 if (is_valid_policy_hnd(&pol
))
994 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1002 /****************************************************************************
1003 ****************************************************************************/
1005 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1006 TALLOC_CTX
*mem_ctx
,
1007 int argc
, const char **argv
)
1009 WERROR werror
= WERR_OK
;
1011 union spoolss_DriverInfo
*info
;
1012 uint32_t i
, j
, count
;
1015 printf("Usage: enumdrivers [level]\n");
1020 level
= atoi(argv
[1]);
1024 /* loop through and print driver info level for each architecture */
1025 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1026 /* check to see if we already asked for this architecture string */
1028 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1032 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1033 cli
->srv_name_slash
,
1034 archi_table
[i
].long_archi
,
1040 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1041 printf("Server does not support environment [%s]\n",
1042 archi_table
[i
].long_archi
);
1051 if (!W_ERROR_IS_OK(werror
)) {
1052 printf("Error getting driver for environment [%s] - %d\n",
1053 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1057 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1061 for (j
=0; j
< count
; j
++) {
1062 display_print_driver1(&info
[j
].info1
);
1066 for (j
=0; j
< count
; j
++) {
1067 display_print_driver2(&info
[j
].info2
);
1071 for (j
=0; j
< count
; j
++) {
1072 display_print_driver3(&info
[j
].info3
);
1076 printf("unknown info level %d\n", level
);
1077 return WERR_UNKNOWN_LEVEL
;
1084 /****************************************************************************
1085 ****************************************************************************/
1087 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1089 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1092 /****************************************************************************
1093 ****************************************************************************/
1095 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1096 TALLOC_CTX
*mem_ctx
,
1097 int argc
, const char **argv
)
1101 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1104 union spoolss_DriverDirectoryInfo info
;
1108 printf("Usage: %s [environment]\n", argv
[0]);
1112 /* Get the arguments need to open the printer handle */
1118 /* Get the directory. Only use Info level 1 */
1120 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1121 cli
->srv_name_slash
,
1129 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1131 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1133 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1134 cli
->srv_name_slash
,
1144 if (W_ERROR_IS_OK(result
)) {
1145 display_printdriverdir_1(&info
.info1
);
1151 /****************************************************************************
1152 ****************************************************************************/
1154 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1155 struct spoolss_AddDriverInfo3
*info
,
1161 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1163 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1165 info
->version
= archi_table
[i
].version
;
1166 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1171 if (archi_table
[i
].long_archi
== NULL
)
1173 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1180 /**************************************************************************
1181 wrapper for strtok to get the next parameter from a delimited list.
1182 Needed to handle the empty parameter string denoted by "NULL"
1183 *************************************************************************/
1185 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1186 const char *delim
, const char **dest
,
1191 /* get the next token */
1192 ptr
= strtok_r(str
, delim
, saveptr
);
1194 /* a string of 'NULL' is used to represent an empty
1195 parameter because two consecutive delimiters
1196 will not return an empty string. See man strtok(3)
1198 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1203 *dest
= talloc_strdup(mem_ctx
, ptr
);
1209 /********************************************************************************
1210 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1211 string in the form of
1212 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1213 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1214 <Default Data Type>:<Comma Separated list of Files>
1215 *******************************************************************************/
1217 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1222 char *saveptr
= NULL
;
1223 struct spoolss_StringArray
*deps
;
1224 const char **file_array
= NULL
;
1227 /* fill in the UNISTR fields */
1228 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1229 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1230 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1231 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1232 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1233 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1234 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1236 /* <Comma Separated List of Dependent Files> */
1237 /* save the beginning of the string */
1238 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1241 /* begin to strip out each filename */
1242 str
= strtok_r(str
, ",", &saveptr
);
1244 /* no dependent files, we are done */
1249 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1254 while (str
!= NULL
) {
1255 add_string_to_array(deps
, str
, &file_array
, &count
);
1256 str
= strtok_r(NULL
, ",", &saveptr
);
1259 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1260 if (!deps
->string
) {
1264 for (i
=0; i
< count
; i
++) {
1265 deps
->string
[i
] = file_array
[i
];
1268 r
->dependent_files
= deps
;
1273 /****************************************************************************
1274 ****************************************************************************/
1276 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1277 TALLOC_CTX
*mem_ctx
,
1278 int argc
, const char **argv
)
1283 struct spoolss_AddDriverInfoCtr info_ctr
;
1284 struct spoolss_AddDriverInfo3 info3
;
1288 /* parse the command arguments */
1289 if (argc
!= 3 && argc
!= 4)
1291 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1292 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1293 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1294 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1295 printf ("\t[version]\n");
1300 /* Fill in the spoolss_AddDriverInfo3 struct */
1303 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1305 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1306 return WERR_INVALID_PARAM
;
1309 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1311 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1312 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1314 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1315 return WERR_INVALID_PARAM
;
1318 /* if printer driver version specified, override the default version
1319 * used by the architecture. This allows installation of Windows
1320 * 2000 (version 3) printer drivers. */
1323 info3
.version
= atoi(argv
[3]);
1327 info_ctr
.level
= level
;
1328 info_ctr
.info
.info3
= &info3
;
1330 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1331 cli
->srv_name_slash
,
1334 if (!NT_STATUS_IS_OK(status
)) {
1335 return ntstatus_to_werror(status
);
1337 if (W_ERROR_IS_OK(result
)) {
1338 printf ("Printer Driver %s successfully installed.\n",
1346 /****************************************************************************
1347 ****************************************************************************/
1349 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1350 TALLOC_CTX
*mem_ctx
,
1351 int argc
, const char **argv
)
1354 struct spoolss_SetPrinterInfoCtr info_ctr
;
1355 struct spoolss_SetPrinterInfo2 info2
;
1357 /* parse the command arguments */
1360 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1364 /* Fill in the DRIVER_INFO_2 struct */
1367 info2
.printername
= argv
[1];
1368 info2
.drivername
= argv
[3];
1369 info2
.sharename
= argv
[2];
1370 info2
.portname
= argv
[4];
1371 info2
.comment
= "Created by rpcclient";
1372 info2
.printprocessor
= "winprint";
1373 info2
.datatype
= "RAW";
1374 info2
.devmode
= NULL
;
1375 info2
.secdesc
= NULL
;
1376 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1378 info2
.defaultpriority
= 0;
1379 info2
.starttime
= 0;
1380 info2
.untiltime
= 0;
1382 /* These three fields must not be used by AddPrinter()
1383 as defined in the MS Platform SDK documentation..
1387 info2.averageppm = 0;
1391 info_ctr
.info
.info2
= &info2
;
1393 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1395 if (W_ERROR_IS_OK(result
))
1396 printf ("Printer %s successfully installed.\n", argv
[1]);
1401 /****************************************************************************
1402 ****************************************************************************/
1404 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1405 TALLOC_CTX
*mem_ctx
,
1406 int argc
, const char **argv
)
1412 const char *printername
;
1413 union spoolss_PrinterInfo info
;
1414 struct spoolss_SetPrinterInfoCtr info_ctr
;
1415 struct spoolss_DevmodeContainer devmode_ctr
;
1416 struct sec_desc_buf secdesc_ctr
;
1418 ZERO_STRUCT(devmode_ctr
);
1419 ZERO_STRUCT(secdesc_ctr
);
1421 /* parse the command arguments */
1424 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1428 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1430 /* Get a printer handle */
1432 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1436 if (!W_ERROR_IS_OK(result
))
1439 /* Get printer info */
1441 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1446 if (!W_ERROR_IS_OK(result
)) {
1447 printf ("Unable to retrieve printer information!\n");
1451 /* Set the printer driver */
1453 info
.info2
.drivername
= argv
[2];
1454 info
.info2
.devmode
= NULL
;
1455 info
.info2
.secdesc
= NULL
;
1458 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
1460 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1467 if (!W_ERROR_IS_OK(result
)) {
1468 printf("SetPrinter call failed!\n");
1472 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1477 if (is_valid_policy_hnd(&pol
))
1478 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1484 /****************************************************************************
1485 ****************************************************************************/
1487 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1488 TALLOC_CTX
*mem_ctx
,
1489 int argc
, const char **argv
)
1491 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1497 const char *arch
= NULL
;
1498 uint32_t delete_flags
= 0;
1500 /* parse the command arguments */
1501 if (argc
< 2 || argc
> 4) {
1502 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1509 vers
= atoi (argv
[3]);
1512 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1515 /* delete the driver for all architectures */
1516 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1518 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1521 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1524 /* make the call to remove the driver */
1525 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1526 cli
->srv_name_slash
,
1527 archi_table
[i
].long_archi
,
1530 archi_table
[i
].version
,
1533 if ( !W_ERROR_IS_OK(result
) )
1535 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1536 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1537 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1542 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1543 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1552 /****************************************************************************
1553 ****************************************************************************/
1555 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1556 TALLOC_CTX
*mem_ctx
,
1557 int argc
, const char **argv
)
1559 WERROR result
= WERR_OK
;
1563 /* parse the command arguments */
1565 printf ("Usage: %s <driver>\n", argv
[0]);
1569 /* delete the driver for all architectures */
1570 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1571 /* make the call to remove the driver */
1572 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1573 cli
->srv_name_slash
,
1574 archi_table
[i
].long_archi
,
1577 if (!NT_STATUS_IS_OK(status
)) {
1580 if ( !W_ERROR_IS_OK(result
) ) {
1581 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1582 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1583 argv
[1], archi_table
[i
].long_archi
,
1587 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1588 archi_table
[i
].long_archi
);
1595 /****************************************************************************
1596 ****************************************************************************/
1598 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1599 TALLOC_CTX
*mem_ctx
,
1600 int argc
, const char **argv
)
1604 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1607 union spoolss_PrintProcessorDirectoryInfo info
;
1610 /* parse the command arguments */
1612 printf ("Usage: %s [environment]\n", argv
[0]);
1617 environment
= argv
[1];
1620 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1621 cli
->srv_name_slash
,
1629 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1631 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1633 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1634 cli
->srv_name_slash
,
1644 if (W_ERROR_IS_OK(result
)) {
1645 printf("%s\n", info
.info1
.directory_name
);
1651 /****************************************************************************
1652 ****************************************************************************/
1654 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1655 int argc
, const char **argv
)
1660 const char *printername
;
1661 union spoolss_AddFormInfo info
;
1662 struct spoolss_AddFormInfo1 info1
;
1663 struct spoolss_AddFormInfo2 info2
;
1666 /* Parse the command arguments */
1668 if (argc
< 3 || argc
> 5) {
1669 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
1673 /* Get a printer handle */
1675 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1677 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1681 if (!W_ERROR_IS_OK(werror
))
1684 /* Dummy up some values for the form data */
1687 level
= atoi(argv
[3]);
1692 info1
.flags
= SPOOLSS_FORM_USER
;
1693 info1
.form_name
= argv
[2];
1694 info1
.size
.width
= 100;
1695 info1
.size
.height
= 100;
1696 info1
.area
.left
= 0;
1697 info1
.area
.top
= 10;
1698 info1
.area
.right
= 20;
1699 info1
.area
.bottom
= 30;
1701 info
.info1
= &info1
;
1705 info2
.flags
= SPOOLSS_FORM_USER
;
1706 info2
.form_name
= argv
[2];
1707 info2
.size
.width
= 100;
1708 info2
.size
.height
= 100;
1709 info2
.area
.left
= 0;
1710 info2
.area
.top
= 10;
1711 info2
.area
.right
= 20;
1712 info2
.area
.bottom
= 30;
1713 info2
.keyword
= argv
[2];
1714 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
1715 info2
.mui_dll
= NULL
;
1716 info2
.ressource_id
= 0;
1717 info2
.display_name
= argv
[2];
1720 info
.info2
= &info2
;
1728 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
1735 if (is_valid_policy_hnd(&handle
))
1736 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1741 /****************************************************************************
1742 ****************************************************************************/
1744 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1745 int argc
, const char **argv
)
1750 const char *printername
;
1751 union spoolss_AddFormInfo info
;
1752 struct spoolss_AddFormInfo1 info1
;
1754 /* Parse the command arguments */
1757 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1761 /* Get a printer handle */
1763 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1765 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1767 SEC_FLAG_MAXIMUM_ALLOWED
,
1769 if (!W_ERROR_IS_OK(werror
))
1772 /* Dummy up some values for the form data */
1774 info1
.flags
= SPOOLSS_FORM_PRINTER
;
1775 info1
.size
.width
= 100;
1776 info1
.size
.height
= 100;
1777 info1
.area
.left
= 0;
1778 info1
.area
.top
= 1000;
1779 info1
.area
.right
= 2000;
1780 info1
.area
.bottom
= 3000;
1781 info1
.form_name
= argv
[2];
1783 info
.info1
= &info1
;
1787 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
1795 if (is_valid_policy_hnd(&handle
))
1796 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1801 /****************************************************************************
1802 ****************************************************************************/
1804 static const char *get_form_flag(int form_flag
)
1806 switch (form_flag
) {
1807 case SPOOLSS_FORM_USER
:
1809 case SPOOLSS_FORM_BUILTIN
:
1810 return "FORM_BUILTIN";
1811 case SPOOLSS_FORM_PRINTER
:
1812 return "FORM_PRINTER";
1818 /****************************************************************************
1819 ****************************************************************************/
1821 static void display_form_info1(struct spoolss_FormInfo1
*r
)
1824 "\tflag: %s (%d)\n" \
1825 "\twidth: %d, length: %d\n" \
1826 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1827 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
1828 r
->size
.width
, r
->size
.height
,
1829 r
->area
.left
, r
->area
.right
,
1830 r
->area
.top
, r
->area
.bottom
);
1833 /****************************************************************************
1834 ****************************************************************************/
1836 static void display_form_info2(struct spoolss_FormInfo2
*r
)
1839 "\tflag: %s (%d)\n" \
1840 "\twidth: %d, length: %d\n" \
1841 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
1842 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
1843 r
->size
.width
, r
->size
.height
,
1844 r
->area
.left
, r
->area
.right
,
1845 r
->area
.top
, r
->area
.bottom
);
1846 printf("\tkeyword: %s\n", r
->keyword
);
1847 printf("\tstring_type: 0x%08x\n", r
->string_type
);
1848 printf("\tmui_dll: %s\n", r
->mui_dll
);
1849 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
1850 printf("\tdisplay_name: %s\n", r
->display_name
);
1851 printf("\tlang_id: %d\n", r
->lang_id
);
1855 /****************************************************************************
1856 ****************************************************************************/
1858 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1859 int argc
, const char **argv
)
1864 const char *printername
;
1866 uint32_t offered
= 0;
1867 union spoolss_FormInfo info
;
1871 /* Parse the command arguments */
1873 if (argc
< 3 || argc
> 5) {
1874 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
1878 /* Get a printer handle */
1880 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1882 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1884 SEC_FLAG_MAXIMUM_ALLOWED
,
1886 if (!W_ERROR_IS_OK(werror
))
1890 level
= atoi(argv
[3]);
1895 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
1904 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
1905 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1907 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
1918 if (!NT_STATUS_IS_OK(status
)) {
1924 display_form_info1(&info
.info1
);
1927 display_form_info2(&info
.info2
);
1932 if (is_valid_policy_hnd(&handle
))
1933 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1938 /****************************************************************************
1939 ****************************************************************************/
1941 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
1942 TALLOC_CTX
*mem_ctx
, int argc
,
1948 const char *printername
;
1950 /* Parse the command arguments */
1953 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1957 /* Get a printer handle */
1959 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1961 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1963 SEC_FLAG_MAXIMUM_ALLOWED
,
1965 if (!W_ERROR_IS_OK(werror
))
1968 /* Delete the form */
1970 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
1974 if (!NT_STATUS_IS_OK(status
)) {
1975 return ntstatus_to_werror(status
);
1979 if (is_valid_policy_hnd(&handle
))
1980 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1985 /****************************************************************************
1986 ****************************************************************************/
1988 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
1989 TALLOC_CTX
*mem_ctx
, int argc
,
1994 const char *printername
;
1995 uint32 num_forms
, level
= 1, i
;
1996 union spoolss_FormInfo
*forms
;
1998 /* Parse the command arguments */
2000 if (argc
< 2 || argc
> 4) {
2001 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2005 /* Get a printer handle */
2007 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2009 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2011 SEC_FLAG_MAXIMUM_ALLOWED
,
2013 if (!W_ERROR_IS_OK(werror
))
2017 level
= atoi(argv
[2]);
2020 /* Enumerate forms */
2022 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2029 if (!W_ERROR_IS_OK(werror
))
2032 /* Display output */
2034 for (i
= 0; i
< num_forms
; i
++) {
2037 display_form_info1(&forms
[i
].info1
);
2040 display_form_info2(&forms
[i
].info2
);
2046 if (is_valid_policy_hnd(&handle
))
2047 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2052 /****************************************************************************
2053 ****************************************************************************/
2055 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2056 TALLOC_CTX
*mem_ctx
,
2057 int argc
, const char **argv
)
2060 const char *printername
;
2062 union spoolss_PrinterInfo info
;
2063 REGISTRY_VALUE value
;
2064 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2066 /* parse the command arguments */
2068 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2069 " <value> <data>\n",
2071 result
= WERR_INVALID_PARAM
;
2075 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2077 value
.type
= REG_NONE
;
2079 if (strequal(argv
[2], "string")) {
2080 value
.type
= REG_SZ
;
2083 if (strequal(argv
[2], "binary")) {
2084 value
.type
= REG_BINARY
;
2087 if (strequal(argv
[2], "dword")) {
2088 value
.type
= REG_DWORD
;
2091 if (strequal(argv
[2], "multistring")) {
2092 value
.type
= REG_MULTI_SZ
;
2095 if (value
.type
== REG_NONE
) {
2096 printf("Unknown data type: %s\n", argv
[2]);
2097 result
= WERR_INVALID_PARAM
;
2101 /* get a printer handle */
2103 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2105 SEC_FLAG_MAXIMUM_ALLOWED
,
2107 if (!W_ERROR_IS_OK(result
))
2110 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2115 if (!W_ERROR_IS_OK(result
))
2118 printf("%s\n", current_timestring(tmp_ctx
, True
));
2119 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2121 /* Set the printer data */
2123 fstrcpy(value
.valuename
, argv
[3]);
2125 switch (value
.type
) {
2128 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2129 value
.size
= data
.uni_str_len
* 2;
2131 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, data
.buffer
,
2134 value
.data_p
= NULL
;
2139 uint32 data
= strtoul(argv
[4], NULL
, 10);
2140 value
.size
= sizeof(data
);
2142 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, &data
,
2145 value
.data_p
= NULL
;
2150 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2151 value
.data_p
= data
.data
;
2152 value
.size
= data
.length
;
2155 case REG_MULTI_SZ
: {
2160 for (i
=4; i
<argc
; i
++) {
2161 if (strcmp(argv
[i
], "NULL") == 0) {
2164 len
+= strlen(argv
[i
])+1;
2168 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2169 if (value
.data_p
== NULL
) {
2170 result
= WERR_NOMEM
;
2174 p
= (char *)value
.data_p
;
2176 for (i
=4; i
<argc
; i
++) {
2177 size_t l
= (strlen(argv
[i
])+1)*2;
2178 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2182 SMB_ASSERT(len
== 0);
2186 printf("Unknown data type: %s\n", argv
[2]);
2187 result
= WERR_INVALID_PARAM
;
2191 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2193 if (!W_ERROR_IS_OK(result
)) {
2194 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2197 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2199 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2204 if (!W_ERROR_IS_OK(result
))
2207 printf("%s\n", current_timestring(tmp_ctx
, True
));
2208 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2212 TALLOC_FREE(tmp_ctx
);
2213 if (is_valid_policy_hnd(&pol
))
2214 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2219 /****************************************************************************
2220 ****************************************************************************/
2222 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2224 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2225 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2229 /****************************************************************************
2230 ****************************************************************************/
2232 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2234 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2235 r
->position
, r
->job_id
,
2236 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2237 r
->total_pages
, r
->size
);
2240 /****************************************************************************
2241 ****************************************************************************/
2243 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2245 printf("jobid[%d], next_jobid[%d]\n",
2246 r
->job_id
, r
->next_job_id
);
2249 /****************************************************************************
2250 ****************************************************************************/
2252 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2254 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2255 r
->position
, r
->job_id
,
2256 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2257 r
->total_pages
, r
->size
, r
->size_high
);
2260 /****************************************************************************
2261 ****************************************************************************/
2263 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2264 TALLOC_CTX
*mem_ctx
, int argc
,
2268 uint32_t level
= 1, count
, i
;
2269 const char *printername
;
2271 union spoolss_JobInfo
*info
;
2273 if (argc
< 2 || argc
> 3) {
2274 printf("Usage: %s printername [level]\n", argv
[0]);
2279 level
= atoi(argv
[2]);
2282 /* Open printer handle */
2284 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2286 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2288 SEC_FLAG_MAXIMUM_ALLOWED
,
2290 if (!W_ERROR_IS_OK(result
))
2293 /* Enumerate ports */
2295 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2303 if (!W_ERROR_IS_OK(result
)) {
2307 for (i
= 0; i
< count
; i
++) {
2310 display_job_info1(&info
[i
].info1
);
2313 display_job_info2(&info
[i
].info2
);
2316 d_printf("unknown info level %d\n", level
);
2322 if (is_valid_policy_hnd(&hnd
)) {
2323 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2329 /****************************************************************************
2330 ****************************************************************************/
2332 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2333 TALLOC_CTX
*mem_ctx
, int argc
,
2337 const char *printername
;
2338 struct policy_handle hnd
;
2341 union spoolss_JobInfo info
;
2343 if (argc
< 3 || argc
> 4) {
2344 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2348 job_id
= atoi(argv
[2]);
2351 level
= atoi(argv
[3]);
2354 /* Open printer handle */
2356 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2358 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2360 SEC_FLAG_MAXIMUM_ALLOWED
,
2362 if (!W_ERROR_IS_OK(result
)) {
2366 /* Enumerate ports */
2368 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2375 if (!W_ERROR_IS_OK(result
)) {
2381 display_job_info1(&info
.info1
);
2384 display_job_info2(&info
.info2
);
2387 display_job_info3(&info
.info3
);
2390 display_job_info4(&info
.info4
);
2393 d_printf("unknown info level %d\n", level
);
2398 if (is_valid_policy_hnd(&hnd
)) {
2399 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2406 /****************************************************************************
2407 ****************************************************************************/
2409 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2410 TALLOC_CTX
*mem_ctx
, int argc
,
2414 uint32 i
=0, val_needed
, data_needed
;
2415 const char *printername
;
2419 printf("Usage: %s printername\n", argv
[0]);
2423 /* Open printer handle */
2425 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2427 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2429 SEC_FLAG_MAXIMUM_ALLOWED
,
2431 if (!W_ERROR_IS_OK(result
))
2434 /* Enumerate data */
2436 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2437 &val_needed
, &data_needed
,
2439 while (W_ERROR_IS_OK(result
)) {
2440 REGISTRY_VALUE value
;
2441 result
= rpccli_spoolss_enumprinterdata(
2442 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2443 data_needed
, 0, 0, &value
);
2444 if (W_ERROR_IS_OK(result
))
2445 display_reg_value(value
);
2447 if (W_ERROR_V(result
) == ERRnomoreitems
)
2448 result
= W_ERROR(ERRsuccess
);
2451 if (is_valid_policy_hnd(&hnd
))
2452 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2457 /****************************************************************************
2458 ****************************************************************************/
2460 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2461 TALLOC_CTX
*mem_ctx
, int argc
,
2466 const char *printername
;
2467 const char *keyname
= NULL
;
2469 REGVAL_CTR
*ctr
= NULL
;
2472 printf("Usage: %s printername <keyname>\n", argv
[0]);
2478 /* Open printer handle */
2480 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2482 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2484 SEC_FLAG_MAXIMUM_ALLOWED
,
2486 if (!W_ERROR_IS_OK(result
))
2489 /* Enumerate subkeys */
2491 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2494 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2496 if (!W_ERROR_IS_OK(result
))
2499 for (i
=0; i
< ctr
->num_values
; i
++) {
2500 display_reg_value(*(ctr
->values
[i
]));
2506 if (is_valid_policy_hnd(&hnd
))
2507 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2512 /****************************************************************************
2513 ****************************************************************************/
2515 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2516 TALLOC_CTX
*mem_ctx
, int argc
,
2520 const char *printername
;
2521 const char *keyname
= NULL
;
2523 uint16
*keylist
= NULL
, *curkey
;
2525 if (argc
< 2 || argc
> 3) {
2526 printf("Usage: %s printername [keyname]\n", argv
[0]);
2535 /* Open printer handle */
2537 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2539 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2541 SEC_FLAG_MAXIMUM_ALLOWED
,
2543 if (!W_ERROR_IS_OK(result
))
2546 /* Enumerate subkeys */
2548 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2550 if (!W_ERROR_IS_OK(result
))
2554 while (*curkey
!= 0) {
2555 char *subkey
= NULL
;
2556 rpcstr_pull_talloc(mem_ctx
, &subkey
, curkey
, -1,
2561 printf("%s\n", subkey
);
2562 curkey
+= strlen(subkey
) + 1;
2569 if (is_valid_policy_hnd(&hnd
))
2570 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2575 /****************************************************************************
2576 ****************************************************************************/
2578 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2579 TALLOC_CTX
*mem_ctx
, int argc
,
2582 const char *printername
;
2583 const char *clientname
;
2587 struct spoolss_NotifyOption option
;
2590 printf("Usage: %s printername\n", argv
[0]);
2597 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2599 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2601 SEC_FLAG_MAXIMUM_ALLOWED
,
2603 if (!W_ERROR_IS_OK(result
)) {
2604 printf("Error opening %s\n", argv
[1]);
2608 /* Create spool options */
2613 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
2614 if (option
.types
== NULL
) {
2615 result
= WERR_NOMEM
;
2619 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
2620 option
.types
[0].count
= 1;
2621 option
.types
[0].fields
= talloc_array(mem_ctx
, enum spoolss_Field
, 1);
2622 if (option
.types
[0].fields
== NULL
) {
2623 result
= WERR_NOMEM
;
2626 option
.types
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2628 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
2629 option
.types
[1].count
= 1;
2630 option
.types
[1].fields
= talloc_array(mem_ctx
, enum spoolss_Field
, 1);
2631 if (option
.types
[1].fields
== NULL
) {
2632 result
= WERR_NOMEM
;
2635 option
.types
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2637 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
2639 result
= WERR_NOMEM
;
2645 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
2653 if (!W_ERROR_IS_OK(result
)) {
2654 printf("Error rffpcnex %s\n", argv
[1]);
2659 if (is_valid_policy_hnd(&hnd
))
2660 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2665 /****************************************************************************
2666 ****************************************************************************/
2668 static bool compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2669 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2671 union spoolss_PrinterInfo info1
, info2
;
2673 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2675 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
2676 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
2681 if ( !W_ERROR_IS_OK(werror
) ) {
2682 printf("failed (%s)\n", win_errstr(werror
));
2683 talloc_destroy(mem_ctx
);
2688 printf("Retrieving printer properties for %s...", cli2
->desthost
);
2689 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
2694 if ( !W_ERROR_IS_OK(werror
) ) {
2695 printf("failed (%s)\n", win_errstr(werror
));
2696 talloc_destroy(mem_ctx
);
2701 talloc_destroy(mem_ctx
);
2706 /****************************************************************************
2707 ****************************************************************************/
2709 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2710 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2712 union spoolss_PrinterInfo info1
, info2
;
2714 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2715 SEC_DESC
*sd1
, *sd2
;
2719 printf("Retrieving printer security for %s...", cli1
->desthost
);
2720 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
2725 if ( !W_ERROR_IS_OK(werror
) ) {
2726 printf("failed (%s)\n", win_errstr(werror
));
2732 printf("Retrieving printer security for %s...", cli2
->desthost
);
2733 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
2738 if ( !W_ERROR_IS_OK(werror
) ) {
2739 printf("failed (%s)\n", win_errstr(werror
));
2748 sd1
= info1
.info3
.secdesc
;
2749 sd2
= info2
.info3
.secdesc
;
2751 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2752 printf("NULL secdesc!\n");
2757 if (!sec_desc_equal( sd1
, sd2
) ) {
2758 printf("Security Descriptors *not* equal!\n");
2763 printf("Security descriptors match\n");
2766 talloc_destroy(mem_ctx
);
2771 /****************************************************************************
2772 ****************************************************************************/
2774 extern struct user_auth_info
*rpcclient_auth_info
;
2776 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2777 TALLOC_CTX
*mem_ctx
, int argc
,
2780 const char *printername
;
2781 char *printername_path
= NULL
;
2782 struct cli_state
*cli_server2
= NULL
;
2783 struct rpc_pipe_client
*cli2
= NULL
;
2784 POLICY_HND hPrinter1
, hPrinter2
;
2789 printf("Usage: %s <printer> <server>\n", argv
[0]);
2793 printername
= argv
[1];
2795 /* first get the connection to the remote server */
2797 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
2800 get_cmdline_auth_info_username(rpcclient_auth_info
),
2802 get_cmdline_auth_info_password(rpcclient_auth_info
),
2803 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2804 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
2806 if ( !NT_STATUS_IS_OK(nt_status
) )
2807 return WERR_GENERAL_FAILURE
;
2809 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &syntax_spoolss
,
2811 if (!NT_STATUS_IS_OK(nt_status
)) {
2812 printf("failed to open spoolss pipe on server %s (%s)\n",
2813 argv
[2], nt_errstr(nt_status
));
2814 return WERR_GENERAL_FAILURE
;
2817 /* now open up both printers */
2819 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
2821 printf("Opening %s...", printername_path
);
2823 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2827 if ( !W_ERROR_IS_OK(werror
) ) {
2828 printf("failed (%s)\n", win_errstr(werror
));
2833 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
2835 printf("Opening %s...", printername_path
);
2836 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
2840 if ( !W_ERROR_IS_OK(werror
) ) {
2841 printf("failed (%s)\n", win_errstr(werror
));
2846 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2847 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2849 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2856 printf("Closing printers...");
2857 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
2858 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
2861 /* close the second remote connection */
2863 cli_shutdown( cli_server2
);
2867 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
2869 printf("print_processor_name: %s\n", r
->print_processor_name
);
2872 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
2873 TALLOC_CTX
*mem_ctx
, int argc
,
2877 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
2878 uint32_t num_procs
, level
= 1, i
;
2879 union spoolss_PrintProcessorInfo
*procs
;
2881 /* Parse the command arguments */
2883 if (argc
< 1 || argc
> 4) {
2884 printf ("Usage: %s [environment] [level]\n", argv
[0]);
2889 environment
= argv
[1];
2893 level
= atoi(argv
[2]);
2896 /* Enumerate Print Processors */
2898 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
2899 cli
->srv_name_slash
,
2905 if (!W_ERROR_IS_OK(werror
))
2908 /* Display output */
2910 for (i
= 0; i
< num_procs
; i
++) {
2913 display_proc_info1(&procs
[i
].info1
);
2922 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
2924 printf("name_array: %s\n", r
->name_array
);
2927 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
2928 TALLOC_CTX
*mem_ctx
, int argc
,
2932 const char *print_processor_name
= "winprint";
2933 uint32_t num_procs
, level
= 1, i
;
2934 union spoolss_PrintProcDataTypesInfo
*procs
;
2936 /* Parse the command arguments */
2938 if (argc
< 1 || argc
> 4) {
2939 printf ("Usage: %s [environment] [level]\n", argv
[0]);
2944 print_processor_name
= argv
[1];
2948 level
= atoi(argv
[2]);
2951 /* Enumerate Print Processor Data Types */
2953 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
2954 cli
->srv_name_slash
,
2955 print_processor_name
,
2960 if (!W_ERROR_IS_OK(werror
))
2963 /* Display output */
2965 for (i
= 0; i
< num_procs
; i
++) {
2968 display_proc_data_types_info1(&procs
[i
].info1
);
2977 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
2979 printf("monitor_name: %s\n", r
->monitor_name
);
2982 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
2984 printf("monitor_name: %s\n", r
->monitor_name
);
2985 printf("environment: %s\n", r
->environment
);
2986 printf("dll_name: %s\n", r
->dll_name
);
2989 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
2990 TALLOC_CTX
*mem_ctx
, int argc
,
2994 uint32_t count
, level
= 1, i
;
2995 union spoolss_MonitorInfo
*info
;
2997 /* Parse the command arguments */
3000 printf("Usage: %s [level]\n", argv
[0]);
3005 level
= atoi(argv
[1]);
3008 /* Enumerate Print Monitors */
3010 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3011 cli
->srv_name_slash
,
3016 if (!W_ERROR_IS_OK(werror
)) {
3020 /* Display output */
3022 for (i
= 0; i
< count
; i
++) {
3025 display_monitor1(&info
[i
].info1
);
3028 display_monitor2(&info
[i
].info2
);
3037 /* List of commands exported by this module */
3038 struct cmd_set spoolss_commands
[] = {
3042 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &syntax_spoolss
, NULL
, "Add a print driver", "" },
3043 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &syntax_spoolss
, NULL
, "Add a printer", "" },
3044 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &syntax_spoolss
, NULL
, "Delete a printer driver", "" },
3045 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &syntax_spoolss
, NULL
, "Delete a printer driver with files", "" },
3046 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &syntax_spoolss
, NULL
, "Enumerate printer data", "" },
3047 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &syntax_spoolss
, NULL
, "Enumerate printer data for a key", "" },
3048 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &syntax_spoolss
, NULL
, "Enumerate printer keys", "" },
3049 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &syntax_spoolss
, NULL
, "Enumerate print jobs", "" },
3050 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &syntax_spoolss
, NULL
, "Get print job", "" },
3051 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &syntax_spoolss
, NULL
, "Enumerate printer ports", "" },
3052 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &syntax_spoolss
, NULL
, "Enumerate installed printer drivers", "" },
3053 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &syntax_spoolss
, NULL
, "Enumerate printers", "" },
3054 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &syntax_spoolss
, NULL
, "Get print driver data", "" },
3055 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &syntax_spoolss
, NULL
, "Get printer driver data with keyname", ""},
3056 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &syntax_spoolss
, NULL
, "Get print driver information", "" },
3057 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &syntax_spoolss
, NULL
, "Get print driver upload directory", "" },
3058 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &syntax_spoolss
, NULL
, "Get printer info", "" },
3059 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &syntax_spoolss
, NULL
, "Open printer handle", "" },
3060 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &syntax_spoolss
, NULL
, "Set printer driver", "" },
3061 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &syntax_spoolss
, NULL
, "Get print processor directory", "" },
3062 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &syntax_spoolss
, NULL
, "Add form", "" },
3063 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &syntax_spoolss
, NULL
, "Set form", "" },
3064 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &syntax_spoolss
, NULL
, "Get form", "" },
3065 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &syntax_spoolss
, NULL
, "Delete form", "" },
3066 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &syntax_spoolss
, NULL
, "Enumerate forms", "" },
3067 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &syntax_spoolss
, NULL
, "Set printer comment", "" },
3068 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &syntax_spoolss
, NULL
, "Set printername", "" },
3069 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &syntax_spoolss
, NULL
, "Set REG_SZ printer data", "" },
3070 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &syntax_spoolss
, NULL
, "Rffpcnex test", "" },
3071 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &syntax_spoolss
, NULL
, "Printer comparison test", "" },
3072 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &syntax_spoolss
, NULL
, "Enumerate Print Processors", "" },
3073 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &syntax_spoolss
, NULL
, "Enumerate Print Processor Data Types", "" },
3074 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &syntax_spoolss
, NULL
, "Enumerate Print Monitors", "" },