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"
28 #include "rpc_client/cli_spoolss.h"
29 #include "rpc_client/init_spoolss.h"
32 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
34 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
35 _cli->srv_name_slash, _arg); \
36 W_ERROR_HAVE_NO_MEMORY(_printername); \
39 /* The version int is used by getdrivers. Note that
40 all architecture strings that support mutliple
41 versions must be grouped together since enumdrivers
42 uses this property to prevent issuing multiple
43 enumdriver calls for the same arch */
46 static const struct print_architecture_table_node archi_table
[]= {
48 {"Windows 4.0", "WIN40", 0 },
49 {"Windows NT x86", "W32X86", 2 },
50 {"Windows NT x86", "W32X86", 3 },
51 {"Windows NT R4000", "W32MIPS", 2 },
52 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
53 {"Windows NT PowerPC", "W32PPC", 2 },
54 {"Windows IA64", "IA64", 3 },
55 {"Windows x64", "x64", 3 },
62 * rpcclient module for SPOOLSS rpc pipe.
64 * This generally just parses and checks command lines, and then calls
65 * a cli_spoolss function.
68 /****************************************************************************
69 function to do the mapping between the long architecture name and
71 ****************************************************************************/
73 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
77 DEBUG(107,("Getting architecture dependant directory\n"));
80 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
81 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
83 if (archi_table
[i
].long_archi
==NULL
) {
84 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
88 /* this might be client code - but shouldn't this be an fstrcpy etc? */
91 DEBUGADD(108,("index: [%d]\n", i
));
92 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
93 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
95 return archi_table
[i
].short_archi
;
98 /****************************************************************************
99 ****************************************************************************/
101 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
103 int argc
, const char **argv
)
106 struct policy_handle hnd
;
109 printf("Usage: %s <printername>\n", argv
[0]);
114 return WERR_GENERAL_FAILURE
;
116 /* Open the printer handle */
118 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
122 if (W_ERROR_IS_OK(werror
)) {
123 printf("Printer %s opened successfully\n", argv
[1]);
124 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
126 if (!W_ERROR_IS_OK(werror
)) {
127 printf("Error closing printer handle! (%s)\n",
128 get_dos_error_msg(werror
));
136 /****************************************************************************
137 ****************************************************************************/
139 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
144 printf("\tprintername:[%s]\n", r
->printername
);
145 printf("\tservername:[%s]\n", r
->servername
);
146 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
147 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
148 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
149 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
150 r
->time
.day
, r
->time
.day_of_week
);
151 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
152 r
->time
.second
, r
->time
.millisecond
);
154 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
155 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
157 printf("\tversion:[0x%x]\n", r
->version
);
158 printf("\tfree_build:[0x%x]\n", r
->free_build
);
159 printf("\tspooling:[0x%x]\n", r
->spooling
);
160 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
161 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
162 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
163 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
164 printf("\tjob_error:[0x%x]\n", r
->job_error
);
165 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
166 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
167 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
168 printf("\tchange_id:[0x%x]\n", r
->change_id
);
169 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
170 printf("\tstatus:[0x%x]\n", r
->status
);
171 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
172 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
173 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
174 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
175 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
176 printf("\treserved2:[0x%x]\n", r
->reserved2
);
177 printf("\treserved3:[0x%x]\n", r
->reserved3
);
182 /****************************************************************************
183 ****************************************************************************/
185 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
187 printf("\tflags:[0x%x]\n", r
->flags
);
188 printf("\tname:[%s]\n", r
->name
);
189 printf("\tdescription:[%s]\n", r
->description
);
190 printf("\tcomment:[%s]\n", r
->comment
);
195 /****************************************************************************
196 ****************************************************************************/
198 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
200 printf("\tservername:[%s]\n", r
->servername
);
201 printf("\tprintername:[%s]\n", r
->printername
);
202 printf("\tsharename:[%s]\n", r
->sharename
);
203 printf("\tportname:[%s]\n", r
->portname
);
204 printf("\tdrivername:[%s]\n", r
->drivername
);
205 printf("\tcomment:[%s]\n", r
->comment
);
206 printf("\tlocation:[%s]\n", r
->location
);
207 printf("\tsepfile:[%s]\n", r
->sepfile
);
208 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
209 printf("\tdatatype:[%s]\n", r
->datatype
);
210 printf("\tparameters:[%s]\n", r
->parameters
);
211 printf("\tattributes:[0x%x]\n", r
->attributes
);
212 printf("\tpriority:[0x%x]\n", r
->priority
);
213 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
214 printf("\tstarttime:[0x%x]\n", r
->starttime
);
215 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
216 printf("\tstatus:[0x%x]\n", r
->status
);
217 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
218 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
221 display_sec_desc(r
->secdesc
);
226 /****************************************************************************
227 ****************************************************************************/
229 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
231 display_sec_desc(r
->secdesc
);
236 /****************************************************************************
237 ****************************************************************************/
239 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
241 printf("\tservername:[%s]\n", r
->servername
);
242 printf("\tprintername:[%s]\n", r
->printername
);
243 printf("\tattributes:[0x%x]\n", r
->attributes
);
247 /****************************************************************************
248 ****************************************************************************/
250 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
252 printf("\tprintername:[%s]\n", r
->printername
);
253 printf("\tportname:[%s]\n", r
->portname
);
254 printf("\tattributes:[0x%x]\n", r
->attributes
);
255 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
256 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
260 /****************************************************************************
261 ****************************************************************************/
263 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
265 printf("\tstatus:[0x%x]\n", r
->status
);
269 /****************************************************************************
270 ****************************************************************************/
272 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
274 printf("\tguid:[%s]\n", r
->guid
);
275 printf("\taction:[0x%x]\n", r
->action
);
279 /****************************************************************************
280 ****************************************************************************/
282 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
284 int argc
, const char **argv
)
288 union spoolss_PrinterInfo
*info
;
291 uint32_t flags
= PRINTER_ENUM_LOCAL
;
294 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
299 level
= atoi(argv
[1]);
305 name
= cli
->srv_name_slash
;
309 flags
= atoi(argv
[3]);
312 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
319 if (W_ERROR_IS_OK(result
)) {
322 printf ("No printers returned.\n");
326 for (i
= 0; i
< count
; i
++) {
329 display_print_info0(&info
[i
].info0
);
332 display_print_info1(&info
[i
].info1
);
335 display_print_info2(&info
[i
].info2
);
338 display_print_info3(&info
[i
].info3
);
341 display_print_info4(&info
[i
].info4
);
344 display_print_info5(&info
[i
].info5
);
347 display_print_info6(&info
[i
].info6
);
350 printf("unknown info level %d\n", level
);
360 /****************************************************************************
361 ****************************************************************************/
363 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
365 printf("\tPort Name:\t[%s]\n", r
->port_name
);
368 /****************************************************************************
369 ****************************************************************************/
371 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
373 printf("\tPort Name:\t[%s]\n", r
->port_name
);
374 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
375 printf("\tDescription:\t[%s]\n", r
->description
);
376 printf("\tPort Type:\t" );
378 int comma
= 0; /* hack */
380 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
384 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
385 printf( "%sWrite", comma
? ", " : "" );
388 /* These two have slightly different interpretations
389 on 95/98/ME but I'm disregarding that for now */
390 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
391 printf( "%sRedirected", comma
? ", " : "" );
394 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
395 printf( "%sNet-Attached", comma
? ", " : "" );
399 printf( "[Unset]\n" );
401 printf("\tReserved:\t[%d]\n", r
->reserved
);
405 /****************************************************************************
406 ****************************************************************************/
408 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
409 TALLOC_CTX
*mem_ctx
, int argc
,
415 union spoolss_PortInfo
*info
;
418 printf("Usage: %s [level]\n", argv
[0]);
423 level
= atoi(argv
[1]);
426 /* Enumerate ports */
428 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
434 if (W_ERROR_IS_OK(result
)) {
437 for (i
= 0; i
< count
; i
++) {
440 display_port_info_1(&info
[i
].info1
);
443 display_port_info_2(&info
[i
].info2
);
446 printf("unknown info level %d\n", level
);
455 /****************************************************************************
456 ****************************************************************************/
458 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
460 int argc
, const char **argv
)
462 struct policy_handle pol
;
465 uint32_t info_level
= 2;
466 union spoolss_PrinterInfo info
;
467 struct spoolss_SetPrinterInfoCtr info_ctr
;
468 struct spoolss_SetPrinterInfo2 info2
;
469 const char *printername
, *comment
= NULL
;
470 struct spoolss_DevmodeContainer devmode_ctr
;
471 struct sec_desc_buf secdesc_ctr
;
473 if (argc
== 1 || argc
> 3) {
474 printf("Usage: %s printername comment\n", argv
[0]);
479 /* Open a printer handle */
484 ZERO_STRUCT(devmode_ctr
);
485 ZERO_STRUCT(secdesc_ctr
);
487 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
489 /* get a printer handle */
490 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
494 if (!W_ERROR_IS_OK(result
))
497 /* Get printer info */
498 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
503 if (!W_ERROR_IS_OK(result
))
507 /* Modify the comment. */
508 info2
.servername
= info
.info2
.servername
;
509 info2
.printername
= info
.info2
.printername
;
510 info2
.sharename
= info
.info2
.sharename
;
511 info2
.portname
= info
.info2
.portname
;
512 info2
.drivername
= info
.info2
.drivername
;
513 info2
.comment
= comment
;
514 info2
.location
= info
.info2
.location
;
515 info2
.devmode_ptr
= 0;
516 info2
.sepfile
= info
.info2
.sepfile
;
517 info2
.printprocessor
= info
.info2
.printprocessor
;
518 info2
.datatype
= info
.info2
.datatype
;
519 info2
.parameters
= info
.info2
.parameters
;
520 info2
.secdesc_ptr
= 0;
521 info2
.attributes
= info
.info2
.attributes
;
522 info2
.priority
= info
.info2
.priority
;
523 info2
.defaultpriority
= info
.info2
.defaultpriority
;
524 info2
.starttime
= info
.info2
.starttime
;
525 info2
.untiltime
= info
.info2
.untiltime
;
526 info2
.status
= info
.info2
.status
;
527 info2
.cjobs
= info
.info2
.cjobs
;
528 info2
.averageppm
= info
.info2
.averageppm
;
531 info_ctr
.info
.info2
= &info2
;
533 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
540 if (W_ERROR_IS_OK(result
))
541 printf("Success in setting comment.\n");
544 if (is_valid_policy_hnd(&pol
))
545 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
550 /****************************************************************************
551 ****************************************************************************/
553 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
555 int argc
, const char **argv
)
557 struct policy_handle pol
;
560 uint32_t info_level
= 2;
561 union spoolss_PrinterInfo info
;
562 const char *printername
,
563 *new_printername
= NULL
;
564 struct spoolss_SetPrinterInfoCtr info_ctr
;
565 struct spoolss_SetPrinterInfo2 info2
;
566 struct spoolss_DevmodeContainer devmode_ctr
;
567 struct sec_desc_buf secdesc_ctr
;
569 ZERO_STRUCT(devmode_ctr
);
570 ZERO_STRUCT(secdesc_ctr
);
572 if (argc
== 1 || argc
> 3) {
573 printf("Usage: %s printername new_printername\n", argv
[0]);
578 /* Open a printer handle */
580 new_printername
= argv
[2];
583 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
585 /* get a printer handle */
586 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
590 if (!W_ERROR_IS_OK(result
))
593 /* Get printer info */
594 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
599 if (!W_ERROR_IS_OK(result
))
602 /* Modify the printername. */
603 info2
.servername
= info
.info2
.servername
;
604 info2
.printername
= new_printername
;
605 info2
.sharename
= info
.info2
.sharename
;
606 info2
.portname
= info
.info2
.portname
;
607 info2
.drivername
= info
.info2
.drivername
;
608 info2
.comment
= info
.info2
.comment
;
609 info2
.location
= info
.info2
.location
;
610 info2
.devmode_ptr
= 0;
611 info2
.sepfile
= info
.info2
.sepfile
;
612 info2
.printprocessor
= info
.info2
.printprocessor
;
613 info2
.datatype
= info
.info2
.datatype
;
614 info2
.parameters
= info
.info2
.parameters
;
615 info2
.secdesc_ptr
= 0;
616 info2
.attributes
= info
.info2
.attributes
;
617 info2
.priority
= info
.info2
.priority
;
618 info2
.defaultpriority
= info
.info2
.defaultpriority
;
619 info2
.starttime
= info
.info2
.starttime
;
620 info2
.untiltime
= info
.info2
.untiltime
;
621 info2
.status
= info
.info2
.status
;
622 info2
.cjobs
= info
.info2
.cjobs
;
623 info2
.averageppm
= info
.info2
.averageppm
;
626 info_ctr
.info
.info2
= &info2
;
628 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
635 if (W_ERROR_IS_OK(result
))
636 printf("Success in setting printername.\n");
639 if (is_valid_policy_hnd(&pol
))
640 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
645 /****************************************************************************
646 ****************************************************************************/
648 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
650 int argc
, const char **argv
)
652 struct policy_handle pol
;
655 const char *printername
;
656 union spoolss_PrinterInfo info
;
658 if (argc
== 1 || argc
> 3) {
659 printf("Usage: %s <printername> [level]\n", argv
[0]);
663 /* Open a printer handle */
665 level
= atoi(argv
[2]);
668 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
670 /* get a printer handle */
672 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
674 SEC_FLAG_MAXIMUM_ALLOWED
,
676 if (!W_ERROR_IS_OK(result
)) {
680 /* Get printer info */
682 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
687 if (!W_ERROR_IS_OK(result
)) {
691 /* Display printer info */
694 display_print_info0(&info
.info0
);
697 display_print_info1(&info
.info1
);
700 display_print_info2(&info
.info2
);
703 display_print_info3(&info
.info3
);
706 display_print_info4(&info
.info4
);
709 display_print_info5(&info
.info5
);
712 display_print_info6(&info
.info6
);
715 display_print_info7(&info
.info7
);
718 printf("unknown info level %d\n", level
);
722 if (is_valid_policy_hnd(&pol
)) {
723 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
729 /****************************************************************************
730 ****************************************************************************/
732 static void display_reg_value(struct regval_blob value
)
734 const char *text
= NULL
;
739 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
740 *((uint32_t *) value
.data_p
));
743 blob
= data_blob_const(value
.data_p
, value
.size
);
744 pull_reg_sz(talloc_tos(), &blob
, &text
);
745 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
748 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
750 printf("%s: REG_BINARY:", value
.valuename
);
752 for (i
=0; i
<len
; i
++) {
753 if (hex
[i
] == '\0') {
768 blob
= data_blob_const(value
.data_p
, value
.size
);
770 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
771 d_printf("pull_reg_multi_sz failed\n");
775 printf("%s: REG_MULTI_SZ: \n", value
.valuename
);
776 for (i
=0; values
[i
] != NULL
; i
++) {
777 d_printf("%s\n", values
[i
]);
783 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
788 /****************************************************************************
789 ****************************************************************************/
791 static void display_printer_data(const char *v
,
792 enum winreg_Type type
,
797 union spoolss_PrinterData r
;
798 DATA_BLOB blob
= data_blob_const(data
, length
);
801 result
= pull_spoolss_PrinterData(talloc_tos(), &blob
, &r
, type
);
802 if (!W_ERROR_IS_OK(result
)) {
808 printf("%s: REG_DWORD: 0x%08x\n", v
, r
.value
);
811 printf("%s: REG_SZ: %s\n", v
, r
.string
);
814 char *hex
= hex_encode_talloc(NULL
,
815 r
.binary
.data
, r
.binary
.length
);
817 printf("%s: REG_BINARY:", v
);
819 for (i
=0; i
<len
; i
++) {
820 if (hex
[i
] == '\0') {
833 printf("%s: REG_MULTI_SZ: ", v
);
834 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
835 printf("%s ", r
.string_array
[i
]);
840 printf("%s: unknown type 0x%02x:\n", v
, type
);
845 /****************************************************************************
846 ****************************************************************************/
848 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
850 int argc
, const char **argv
)
852 struct policy_handle pol
;
855 const char *valuename
;
856 enum winreg_Type type
;
861 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
862 printf("<printername> of . queries print server\n");
867 /* Open a printer handle */
869 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
870 fstrcpy(printername
, cli
->srv_name_slash
);
872 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
873 cli
->srv_name_slash
, argv
[1]);
875 /* get a printer handle */
877 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
879 SEC_FLAG_MAXIMUM_ALLOWED
,
881 if (!W_ERROR_IS_OK(result
))
884 /* Get printer info */
886 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
893 if (!W_ERROR_IS_OK(result
))
896 /* Display printer data */
898 display_printer_data(valuename
, type
, data
, needed
);
901 if (is_valid_policy_hnd(&pol
))
902 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
907 /****************************************************************************
908 ****************************************************************************/
910 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
912 int argc
, const char **argv
)
914 struct policy_handle pol
;
918 const char *valuename
, *keyname
;
920 enum winreg_Type type
;
921 uint8_t *data
= NULL
;
922 uint32_t offered
= 0;
926 printf("Usage: %s <printername> <keyname> <valuename>\n",
928 printf("<printername> of . queries print server\n");
934 /* Open a printer handle */
936 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
937 fstrcpy(printername
, cli
->srv_name_slash
);
939 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
940 cli
->srv_name_slash
, argv
[1]);
942 /* get a printer handle */
944 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
946 SEC_FLAG_MAXIMUM_ALLOWED
,
948 if (!W_ERROR_IS_OK(result
))
951 /* Get printer info */
953 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
958 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
967 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
969 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
973 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
984 if (!NT_STATUS_IS_OK(status
)) {
988 if (!W_ERROR_IS_OK(result
))
991 /* Display printer data */
993 display_printer_data(valuename
, type
, data
, needed
);
997 if (is_valid_policy_hnd(&pol
))
998 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1003 /****************************************************************************
1004 ****************************************************************************/
1006 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1012 printf("Printer Driver Info 1:\n");
1013 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1017 /****************************************************************************
1018 ****************************************************************************/
1020 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1026 printf("Printer Driver Info 2:\n");
1027 printf("\tVersion: [%x]\n", r
->version
);
1028 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1029 printf("\tArchitecture: [%s]\n", r
->architecture
);
1030 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1031 printf("\tDatafile: [%s]\n", r
->data_file
);
1032 printf("\tConfigfile: [%s]\n", r
->config_file
);
1036 /****************************************************************************
1037 ****************************************************************************/
1039 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1047 printf("Printer Driver Info 3:\n");
1048 printf("\tVersion: [%x]\n", r
->version
);
1049 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1050 printf("\tArchitecture: [%s]\n", r
->architecture
);
1051 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1052 printf("\tDatafile: [%s]\n", r
->data_file
);
1053 printf("\tConfigfile: [%s]\n", r
->config_file
);
1054 printf("\tHelpfile: [%s]\n", r
->help_file
);
1056 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1057 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1060 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1061 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1065 /****************************************************************************
1066 ****************************************************************************/
1068 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1076 printf("Printer Driver Info 4:\n");
1077 printf("\tVersion: [%x]\n", r
->version
);
1078 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1079 printf("\tArchitecture: [%s]\n", r
->architecture
);
1080 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1081 printf("\tDatafile: [%s]\n", r
->data_file
);
1082 printf("\tConfigfile: [%s]\n", r
->config_file
);
1083 printf("\tHelpfile: [%s]\n", r
->help_file
);
1085 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1086 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1089 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1090 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1092 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1093 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1098 /****************************************************************************
1099 ****************************************************************************/
1101 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1107 printf("Printer Driver Info 5:\n");
1108 printf("\tVersion: [%x]\n", r
->version
);
1109 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1110 printf("\tArchitecture: [%s]\n", r
->architecture
);
1111 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1112 printf("\tDatafile: [%s]\n", r
->data_file
);
1113 printf("\tConfigfile: [%s]\n", r
->config_file
);
1114 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1115 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1116 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1120 /****************************************************************************
1121 ****************************************************************************/
1123 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1131 printf("Printer Driver Info 6:\n");
1132 printf("\tVersion: [%x]\n", r
->version
);
1133 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1134 printf("\tArchitecture: [%s]\n", r
->architecture
);
1135 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1136 printf("\tDatafile: [%s]\n", r
->data_file
);
1137 printf("\tConfigfile: [%s]\n", r
->config_file
);
1138 printf("\tHelpfile: [%s]\n", r
->help_file
);
1140 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1141 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1144 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1145 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1147 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1148 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1151 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1152 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1153 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1154 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1155 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1156 printf("\tProvider: [%s]\n", r
->provider
);
1161 /****************************************************************************
1162 ****************************************************************************/
1164 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1172 printf("Printer Driver Info 8:\n");
1173 printf("\tVersion: [%x]\n", r
->version
);
1174 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1175 printf("\tArchitecture: [%s]\n", r
->architecture
);
1176 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1177 printf("\tDatafile: [%s]\n", r
->data_file
);
1178 printf("\tConfigfile: [%s]\n", r
->config_file
);
1179 printf("\tHelpfile: [%s]\n", r
->help_file
);
1180 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1181 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1183 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1184 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1187 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1188 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1191 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1192 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1193 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1194 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1195 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1196 printf("\tProvider: [%s]\n", r
->provider
);
1197 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1198 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1199 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1200 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1202 printf("\tInf Path: [%s]\n", r
->inf_path
);
1203 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1204 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1205 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1207 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1208 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1209 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1214 /****************************************************************************
1215 ****************************************************************************/
1217 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1218 TALLOC_CTX
*mem_ctx
,
1219 int argc
, const char **argv
)
1221 struct policy_handle pol
;
1224 const char *printername
;
1226 bool success
= false;
1227 union spoolss_DriverInfo info
;
1228 uint32_t server_major_version
;
1229 uint32_t server_minor_version
;
1231 if ((argc
== 1) || (argc
> 3)) {
1232 printf("Usage: %s <printername> [level]\n", argv
[0]);
1236 /* get the arguments need to open the printer handle */
1238 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1241 level
= atoi(argv
[2]);
1244 /* Open a printer handle */
1246 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1250 if (!W_ERROR_IS_OK(werror
)) {
1251 printf("Error opening printer handle for %s!\n", printername
);
1255 /* loop through and print driver info level for each architecture */
1257 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1259 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1261 archi_table
[i
].long_archi
,
1264 archi_table
[i
].version
,
1267 &server_major_version
,
1268 &server_minor_version
);
1269 if (!W_ERROR_IS_OK(werror
)) {
1273 /* need at least one success */
1277 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1281 display_print_driver1(&info
.info1
);
1284 display_print_driver2(&info
.info2
);
1287 display_print_driver3(&info
.info3
);
1290 display_print_driver4(&info
.info4
);
1293 display_print_driver5(&info
.info5
);
1296 display_print_driver6(&info
.info6
);
1299 display_print_driver8(&info
.info8
);
1302 printf("unknown info level %d\n", level
);
1309 if (is_valid_policy_hnd(&pol
)) {
1310 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1320 /****************************************************************************
1321 ****************************************************************************/
1323 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1324 TALLOC_CTX
*mem_ctx
,
1325 const char *architecture
,
1330 union spoolss_DriverInfo
*info
= NULL
;
1333 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1334 cli
->srv_name_slash
,
1341 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1342 printf("Server does not support environment [%s]\n",
1351 if (!W_ERROR_IS_OK(werror
)) {
1352 printf("Error getting driver for environment [%s] - %s\n",
1353 architecture
, win_errstr(werror
));
1357 printf("\n[%s]\n", architecture
);
1361 for (j
=0; j
< count
; j
++) {
1362 display_print_driver1(&info
[j
].info1
);
1366 for (j
=0; j
< count
; j
++) {
1367 display_print_driver2(&info
[j
].info2
);
1371 for (j
=0; j
< count
; j
++) {
1372 display_print_driver3(&info
[j
].info3
);
1376 for (j
=0; j
< count
; j
++) {
1377 display_print_driver4(&info
[j
].info4
);
1381 for (j
=0; j
< count
; j
++) {
1382 display_print_driver5(&info
[j
].info5
);
1386 for (j
=0; j
< count
; j
++) {
1387 display_print_driver6(&info
[j
].info6
);
1391 for (j
=0; j
< count
; j
++) {
1392 display_print_driver8(&info
[j
].info8
);
1396 printf("unknown info level %d\n", level
);
1397 return WERR_UNKNOWN_LEVEL
;
1403 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1404 TALLOC_CTX
*mem_ctx
,
1405 int argc
, const char **argv
)
1407 WERROR werror
= WERR_OK
;
1410 const char *architecture
= NULL
;
1413 printf("Usage: enumdrivers [level] [architecture]\n");
1418 level
= atoi(argv
[1]);
1422 architecture
= argv
[2];
1426 return enum_driver_by_architecture(cli
, mem_ctx
,
1431 /* loop through and print driver info level for each architecture */
1432 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1433 /* check to see if we already asked for this architecture string */
1435 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1439 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1440 archi_table
[i
].long_archi
,
1442 if (!W_ERROR_IS_OK(werror
)) {
1450 /****************************************************************************
1451 ****************************************************************************/
1453 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1455 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1458 /****************************************************************************
1459 ****************************************************************************/
1461 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1462 TALLOC_CTX
*mem_ctx
,
1463 int argc
, const char **argv
)
1467 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1470 union spoolss_DriverDirectoryInfo info
;
1474 printf("Usage: %s [environment]\n", argv
[0]);
1478 /* Get the arguments need to open the printer handle */
1484 /* Get the directory. Only use Info level 1 */
1486 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1487 cli
->srv_name_slash
,
1495 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1497 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1499 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1500 cli
->srv_name_slash
,
1510 if (W_ERROR_IS_OK(result
)) {
1511 display_printdriverdir_1(&info
.info1
);
1517 /****************************************************************************
1518 ****************************************************************************/
1520 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1521 struct spoolss_AddDriverInfo3
*info
,
1527 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1529 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1531 info
->version
= archi_table
[i
].version
;
1532 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1537 if (archi_table
[i
].long_archi
== NULL
)
1539 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1546 /**************************************************************************
1547 wrapper for strtok to get the next parameter from a delimited list.
1548 Needed to handle the empty parameter string denoted by "NULL"
1549 *************************************************************************/
1551 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1552 const char *delim
, const char **dest
,
1557 /* get the next token */
1558 ptr
= strtok_r(str
, delim
, saveptr
);
1560 /* a string of 'NULL' is used to represent an empty
1561 parameter because two consecutive delimiters
1562 will not return an empty string. See man strtok(3)
1564 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1569 *dest
= talloc_strdup(mem_ctx
, ptr
);
1575 /********************************************************************************
1576 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1577 string in the form of
1578 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1579 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1580 <Default Data Type>:<Comma Separated list of Files>
1581 *******************************************************************************/
1583 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1588 char *saveptr
= NULL
;
1589 struct spoolss_StringArray
*deps
;
1590 const char **file_array
= NULL
;
1593 /* fill in the UNISTR fields */
1594 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1595 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1596 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1597 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1598 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1599 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1600 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1602 /* <Comma Separated List of Dependent Files> */
1603 /* save the beginning of the string */
1604 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1607 /* begin to strip out each filename */
1608 str
= strtok_r(str
, ",", &saveptr
);
1610 /* no dependent files, we are done */
1615 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1620 while (str
!= NULL
) {
1621 add_string_to_array(deps
, str
, &file_array
, &count
);
1622 str
= strtok_r(NULL
, ",", &saveptr
);
1625 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1626 if (!deps
->string
) {
1630 for (i
=0; i
< count
; i
++) {
1631 deps
->string
[i
] = file_array
[i
];
1634 r
->dependent_files
= deps
;
1639 /****************************************************************************
1640 ****************************************************************************/
1642 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1643 TALLOC_CTX
*mem_ctx
,
1644 int argc
, const char **argv
)
1649 struct spoolss_AddDriverInfoCtr info_ctr
;
1650 struct spoolss_AddDriverInfo3 info3
;
1654 /* parse the command arguments */
1655 if (argc
!= 3 && argc
!= 4)
1657 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1658 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1659 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1660 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1661 printf ("\t[version]\n");
1666 /* Fill in the spoolss_AddDriverInfo3 struct */
1669 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1671 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1672 return WERR_INVALID_PARAM
;
1675 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1677 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1678 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1680 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1681 return WERR_INVALID_PARAM
;
1684 /* if printer driver version specified, override the default version
1685 * used by the architecture. This allows installation of Windows
1686 * 2000 (version 3) printer drivers. */
1689 info3
.version
= atoi(argv
[3]);
1693 info_ctr
.level
= level
;
1694 info_ctr
.info
.info3
= &info3
;
1696 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1697 cli
->srv_name_slash
,
1700 if (!NT_STATUS_IS_OK(status
)) {
1701 return ntstatus_to_werror(status
);
1703 if (W_ERROR_IS_OK(result
)) {
1704 printf ("Printer Driver %s successfully installed.\n",
1712 /****************************************************************************
1713 ****************************************************************************/
1715 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1716 TALLOC_CTX
*mem_ctx
,
1717 int argc
, const char **argv
)
1720 struct spoolss_SetPrinterInfoCtr info_ctr
;
1721 struct spoolss_SetPrinterInfo2 info2
;
1723 /* parse the command arguments */
1726 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1730 /* Fill in the DRIVER_INFO_2 struct */
1733 info2
.printername
= argv
[1];
1734 info2
.drivername
= argv
[3];
1735 info2
.sharename
= argv
[2];
1736 info2
.portname
= argv
[4];
1737 info2
.comment
= "Created by rpcclient";
1738 info2
.printprocessor
= "winprint";
1739 info2
.datatype
= "RAW";
1740 info2
.devmode_ptr
= 0;
1741 info2
.secdesc_ptr
= 0;
1742 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1744 info2
.defaultpriority
= 0;
1745 info2
.starttime
= 0;
1746 info2
.untiltime
= 0;
1748 /* These three fields must not be used by AddPrinter()
1749 as defined in the MS Platform SDK documentation..
1753 info2.averageppm = 0;
1757 info_ctr
.info
.info2
= &info2
;
1759 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1761 if (W_ERROR_IS_OK(result
))
1762 printf ("Printer %s successfully installed.\n", argv
[1]);
1767 /****************************************************************************
1768 ****************************************************************************/
1770 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1771 TALLOC_CTX
*mem_ctx
,
1772 int argc
, const char **argv
)
1774 struct policy_handle pol
;
1778 const char *printername
;
1779 union spoolss_PrinterInfo info
;
1780 struct spoolss_SetPrinterInfoCtr info_ctr
;
1781 struct spoolss_SetPrinterInfo2 info2
;
1782 struct spoolss_DevmodeContainer devmode_ctr
;
1783 struct sec_desc_buf secdesc_ctr
;
1785 ZERO_STRUCT(devmode_ctr
);
1786 ZERO_STRUCT(secdesc_ctr
);
1788 /* parse the command arguments */
1791 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1795 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1797 /* Get a printer handle */
1799 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1803 if (!W_ERROR_IS_OK(result
))
1806 /* Get printer info */
1808 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1813 if (!W_ERROR_IS_OK(result
)) {
1814 printf ("Unable to retrieve printer information!\n");
1818 /* Set the printer driver */
1820 info2
.servername
= info
.info2
.servername
;
1821 info2
.printername
= info
.info2
.printername
;
1822 info2
.sharename
= info
.info2
.sharename
;
1823 info2
.portname
= info
.info2
.portname
;
1824 info2
.drivername
= argv
[2];
1825 info2
.comment
= info
.info2
.comment
;
1826 info2
.location
= info
.info2
.location
;
1827 info2
.devmode_ptr
= 0;
1828 info2
.sepfile
= info
.info2
.sepfile
;
1829 info2
.printprocessor
= info
.info2
.printprocessor
;
1830 info2
.datatype
= info
.info2
.datatype
;
1831 info2
.parameters
= info
.info2
.parameters
;
1832 info2
.secdesc_ptr
= 0;
1833 info2
.attributes
= info
.info2
.attributes
;
1834 info2
.priority
= info
.info2
.priority
;
1835 info2
.defaultpriority
= info
.info2
.defaultpriority
;
1836 info2
.starttime
= info
.info2
.starttime
;
1837 info2
.untiltime
= info
.info2
.untiltime
;
1838 info2
.status
= info
.info2
.status
;
1839 info2
.cjobs
= info
.info2
.cjobs
;
1840 info2
.averageppm
= info
.info2
.averageppm
;
1843 info_ctr
.info
.info2
= &info2
;
1845 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1852 if (!W_ERROR_IS_OK(result
)) {
1853 printf("SetPrinter call failed!\n");
1857 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1862 if (is_valid_policy_hnd(&pol
))
1863 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1869 /****************************************************************************
1870 ****************************************************************************/
1872 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1873 TALLOC_CTX
*mem_ctx
,
1874 int argc
, const char **argv
)
1876 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1882 const char *arch
= NULL
;
1883 uint32_t delete_flags
= 0;
1885 /* parse the command arguments */
1886 if (argc
< 2 || argc
> 4) {
1887 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1894 vers
= atoi (argv
[3]);
1897 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1900 /* delete the driver for all architectures */
1901 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1903 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1906 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1909 /* make the call to remove the driver */
1910 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1911 cli
->srv_name_slash
,
1912 archi_table
[i
].long_archi
,
1915 archi_table
[i
].version
,
1918 if ( !W_ERROR_IS_OK(result
) )
1920 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1921 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1922 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1927 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1928 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1937 /****************************************************************************
1938 ****************************************************************************/
1940 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1941 TALLOC_CTX
*mem_ctx
,
1942 int argc
, const char **argv
)
1944 WERROR result
= WERR_OK
;
1948 /* parse the command arguments */
1950 printf ("Usage: %s <driver>\n", argv
[0]);
1954 /* delete the driver for all architectures */
1955 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1956 /* make the call to remove the driver */
1957 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1958 cli
->srv_name_slash
,
1959 archi_table
[i
].long_archi
,
1962 if (!NT_STATUS_IS_OK(status
)) {
1965 if ( !W_ERROR_IS_OK(result
) ) {
1966 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1967 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1968 argv
[1], archi_table
[i
].long_archi
,
1972 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1973 archi_table
[i
].long_archi
);
1980 /****************************************************************************
1981 ****************************************************************************/
1983 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1984 TALLOC_CTX
*mem_ctx
,
1985 int argc
, const char **argv
)
1989 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1992 union spoolss_PrintProcessorDirectoryInfo info
;
1995 /* parse the command arguments */
1997 printf ("Usage: %s [environment]\n", argv
[0]);
2002 environment
= argv
[1];
2005 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
2006 cli
->srv_name_slash
,
2014 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2016 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2018 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
2019 cli
->srv_name_slash
,
2029 if (W_ERROR_IS_OK(result
)) {
2030 printf("%s\n", info
.info1
.directory_name
);
2036 /****************************************************************************
2037 ****************************************************************************/
2039 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2040 int argc
, const char **argv
)
2042 struct policy_handle handle
;
2045 const char *printername
;
2046 union spoolss_AddFormInfo info
;
2047 struct spoolss_AddFormInfo1 info1
;
2048 struct spoolss_AddFormInfo2 info2
;
2051 /* Parse the command arguments */
2053 if (argc
< 3 || argc
> 5) {
2054 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2058 /* Get a printer handle */
2060 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2062 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2066 if (!W_ERROR_IS_OK(werror
))
2069 /* Dummy up some values for the form data */
2072 level
= atoi(argv
[3]);
2077 info1
.flags
= SPOOLSS_FORM_USER
;
2078 info1
.form_name
= argv
[2];
2079 info1
.size
.width
= 100;
2080 info1
.size
.height
= 100;
2081 info1
.area
.left
= 0;
2082 info1
.area
.top
= 10;
2083 info1
.area
.right
= 20;
2084 info1
.area
.bottom
= 30;
2086 info
.info1
= &info1
;
2090 info2
.flags
= SPOOLSS_FORM_USER
;
2091 info2
.form_name
= argv
[2];
2092 info2
.size
.width
= 100;
2093 info2
.size
.height
= 100;
2094 info2
.area
.left
= 0;
2095 info2
.area
.top
= 10;
2096 info2
.area
.right
= 20;
2097 info2
.area
.bottom
= 30;
2098 info2
.keyword
= argv
[2];
2099 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2100 info2
.mui_dll
= NULL
;
2101 info2
.ressource_id
= 0;
2102 info2
.display_name
= argv
[2];
2105 info
.info2
= &info2
;
2113 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
2120 if (is_valid_policy_hnd(&handle
))
2121 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2126 /****************************************************************************
2127 ****************************************************************************/
2129 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2130 int argc
, const char **argv
)
2132 struct policy_handle handle
;
2135 const char *printername
;
2136 union spoolss_AddFormInfo info
;
2137 struct spoolss_AddFormInfo1 info1
;
2139 /* Parse the command arguments */
2142 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2146 /* Get a printer handle */
2148 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2150 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2152 SEC_FLAG_MAXIMUM_ALLOWED
,
2154 if (!W_ERROR_IS_OK(werror
))
2157 /* Dummy up some values for the form data */
2159 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2160 info1
.size
.width
= 100;
2161 info1
.size
.height
= 100;
2162 info1
.area
.left
= 0;
2163 info1
.area
.top
= 1000;
2164 info1
.area
.right
= 2000;
2165 info1
.area
.bottom
= 3000;
2166 info1
.form_name
= argv
[2];
2168 info
.info1
= &info1
;
2172 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
2180 if (is_valid_policy_hnd(&handle
))
2181 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2186 /****************************************************************************
2187 ****************************************************************************/
2189 static const char *get_form_flag(int form_flag
)
2191 switch (form_flag
) {
2192 case SPOOLSS_FORM_USER
:
2194 case SPOOLSS_FORM_BUILTIN
:
2195 return "FORM_BUILTIN";
2196 case SPOOLSS_FORM_PRINTER
:
2197 return "FORM_PRINTER";
2203 /****************************************************************************
2204 ****************************************************************************/
2206 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2209 "\tflag: %s (%d)\n" \
2210 "\twidth: %d, length: %d\n" \
2211 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2212 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2213 r
->size
.width
, r
->size
.height
,
2214 r
->area
.left
, r
->area
.right
,
2215 r
->area
.top
, r
->area
.bottom
);
2218 /****************************************************************************
2219 ****************************************************************************/
2221 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2224 "\tflag: %s (%d)\n" \
2225 "\twidth: %d, length: %d\n" \
2226 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2227 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2228 r
->size
.width
, r
->size
.height
,
2229 r
->area
.left
, r
->area
.right
,
2230 r
->area
.top
, r
->area
.bottom
);
2231 printf("\tkeyword: %s\n", r
->keyword
);
2232 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2233 printf("\tmui_dll: %s\n", r
->mui_dll
);
2234 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2235 printf("\tdisplay_name: %s\n", r
->display_name
);
2236 printf("\tlang_id: %d\n", r
->lang_id
);
2240 /****************************************************************************
2241 ****************************************************************************/
2243 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2244 int argc
, const char **argv
)
2246 struct policy_handle handle
;
2249 const char *printername
;
2251 uint32_t offered
= 0;
2252 union spoolss_FormInfo info
;
2256 /* Parse the command arguments */
2258 if (argc
< 3 || argc
> 5) {
2259 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2263 /* Get a printer handle */
2265 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2267 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2269 SEC_FLAG_MAXIMUM_ALLOWED
,
2271 if (!W_ERROR_IS_OK(werror
))
2275 level
= atoi(argv
[3]);
2280 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2289 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2290 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2292 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2303 if (!NT_STATUS_IS_OK(status
)) {
2309 display_form_info1(&info
.info1
);
2312 display_form_info2(&info
.info2
);
2317 if (is_valid_policy_hnd(&handle
))
2318 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2323 /****************************************************************************
2324 ****************************************************************************/
2326 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2327 TALLOC_CTX
*mem_ctx
, int argc
,
2330 struct policy_handle handle
;
2333 const char *printername
;
2335 /* Parse the command arguments */
2338 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2342 /* Get a printer handle */
2344 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2346 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2348 SEC_FLAG_MAXIMUM_ALLOWED
,
2350 if (!W_ERROR_IS_OK(werror
))
2353 /* Delete the form */
2355 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2359 if (!NT_STATUS_IS_OK(status
)) {
2360 return ntstatus_to_werror(status
);
2364 if (is_valid_policy_hnd(&handle
))
2365 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2370 /****************************************************************************
2371 ****************************************************************************/
2373 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2374 TALLOC_CTX
*mem_ctx
, int argc
,
2377 struct policy_handle handle
;
2379 const char *printername
;
2380 uint32_t num_forms
, level
= 1, i
;
2381 union spoolss_FormInfo
*forms
;
2383 /* Parse the command arguments */
2385 if (argc
< 2 || argc
> 4) {
2386 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2390 /* Get a printer handle */
2392 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2394 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2396 SEC_FLAG_MAXIMUM_ALLOWED
,
2398 if (!W_ERROR_IS_OK(werror
))
2402 level
= atoi(argv
[2]);
2405 /* Enumerate forms */
2407 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2414 if (!W_ERROR_IS_OK(werror
))
2417 /* Display output */
2419 for (i
= 0; i
< num_forms
; i
++) {
2422 display_form_info1(&forms
[i
].info1
);
2425 display_form_info2(&forms
[i
].info2
);
2431 if (is_valid_policy_hnd(&handle
))
2432 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2437 /****************************************************************************
2438 ****************************************************************************/
2440 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2441 TALLOC_CTX
*mem_ctx
,
2442 int argc
, const char **argv
)
2446 const char *printername
;
2447 struct policy_handle pol
;
2448 union spoolss_PrinterInfo info
;
2449 enum winreg_Type type
;
2450 union spoolss_PrinterData data
;
2453 /* parse the command arguments */
2455 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2456 " <value> <data>\n",
2461 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2465 if (strequal(argv
[2], "string")) {
2469 if (strequal(argv
[2], "binary")) {
2473 if (strequal(argv
[2], "dword")) {
2477 if (strequal(argv
[2], "multistring")) {
2478 type
= REG_MULTI_SZ
;
2481 if (type
== REG_NONE
) {
2482 printf("Unknown data type: %s\n", argv
[2]);
2483 result
= WERR_INVALID_PARAM
;
2487 /* get a printer handle */
2489 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2491 SEC_FLAG_MAXIMUM_ALLOWED
,
2493 if (!W_ERROR_IS_OK(result
)) {
2497 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2502 if (!W_ERROR_IS_OK(result
)) {
2506 printf("%s\n", current_timestring(mem_ctx
, true));
2507 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2509 /* Set the printer data */
2513 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2514 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2517 data
.value
= strtoul(argv
[4], NULL
, 10);
2520 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2522 case REG_MULTI_SZ
: {
2524 const char **strings
= NULL
;
2526 for (i
=4; i
<argc
; i
++) {
2527 if (strcmp(argv
[i
], "NULL") == 0) {
2530 if (!add_string_to_array(mem_ctx
, argv
[i
],
2533 result
= WERR_NOMEM
;
2537 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2538 if (!data
.string_array
) {
2539 result
= WERR_NOMEM
;
2542 for (i
=0; i
< num_strings
; i
++) {
2543 data
.string_array
[i
] = strings
[i
];
2548 printf("Unknown data type: %s\n", argv
[2]);
2549 result
= WERR_INVALID_PARAM
;
2553 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2554 if (!W_ERROR_IS_OK(result
)) {
2558 status
= rpccli_spoolss_SetPrinterData(cli
, mem_ctx
,
2560 argv
[3], /* value_name */
2565 if (!W_ERROR_IS_OK(result
)) {
2566 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2569 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2571 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2576 if (!W_ERROR_IS_OK(result
)) {
2580 printf("%s\n", current_timestring(mem_ctx
, true));
2581 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2585 if (is_valid_policy_hnd(&pol
)) {
2586 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2592 /****************************************************************************
2593 ****************************************************************************/
2595 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2597 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2598 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2602 /****************************************************************************
2603 ****************************************************************************/
2605 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2607 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2608 r
->position
, r
->job_id
,
2609 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2610 r
->total_pages
, r
->size
);
2613 /****************************************************************************
2614 ****************************************************************************/
2616 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2618 printf("jobid[%d], next_jobid[%d]\n",
2619 r
->job_id
, r
->next_job_id
);
2622 /****************************************************************************
2623 ****************************************************************************/
2625 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2627 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2628 r
->position
, r
->job_id
,
2629 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2630 r
->total_pages
, r
->size
, r
->size_high
);
2633 /****************************************************************************
2634 ****************************************************************************/
2636 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2637 TALLOC_CTX
*mem_ctx
, int argc
,
2641 uint32_t level
= 1, count
, i
;
2642 const char *printername
;
2643 struct policy_handle hnd
;
2644 union spoolss_JobInfo
*info
;
2646 if (argc
< 2 || argc
> 3) {
2647 printf("Usage: %s printername [level]\n", argv
[0]);
2652 level
= atoi(argv
[2]);
2655 /* Open printer handle */
2657 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2659 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2661 SEC_FLAG_MAXIMUM_ALLOWED
,
2663 if (!W_ERROR_IS_OK(result
))
2666 /* Enumerate ports */
2668 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2676 if (!W_ERROR_IS_OK(result
)) {
2680 for (i
= 0; i
< count
; i
++) {
2683 display_job_info1(&info
[i
].info1
);
2686 display_job_info2(&info
[i
].info2
);
2689 d_printf("unknown info level %d\n", level
);
2695 if (is_valid_policy_hnd(&hnd
)) {
2696 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2702 /****************************************************************************
2703 ****************************************************************************/
2705 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2706 TALLOC_CTX
*mem_ctx
, int argc
,
2710 const char *printername
;
2711 struct policy_handle hnd
;
2714 union spoolss_JobInfo info
;
2716 if (argc
< 3 || argc
> 4) {
2717 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2721 job_id
= atoi(argv
[2]);
2724 level
= atoi(argv
[3]);
2727 /* Open printer handle */
2729 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2731 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2733 SEC_FLAG_MAXIMUM_ALLOWED
,
2735 if (!W_ERROR_IS_OK(result
)) {
2739 /* Enumerate ports */
2741 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2748 if (!W_ERROR_IS_OK(result
)) {
2754 display_job_info1(&info
.info1
);
2757 display_job_info2(&info
.info2
);
2760 display_job_info3(&info
.info3
);
2763 display_job_info4(&info
.info4
);
2766 d_printf("unknown info level %d\n", level
);
2771 if (is_valid_policy_hnd(&hnd
)) {
2772 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2778 /****************************************************************************
2779 ****************************************************************************/
2781 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2782 TALLOC_CTX
*mem_ctx
, int argc
,
2787 const char *printername
;
2788 struct policy_handle hnd
;
2790 enum spoolss_JobControl command
;
2793 printf("Usage: %s printername job_id command\n", argv
[0]);
2797 job_id
= atoi(argv
[2]);
2798 command
= atoi(argv
[3]);
2800 /* Open printer handle */
2802 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2804 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2806 SEC_FLAG_MAXIMUM_ALLOWED
,
2808 if (!W_ERROR_IS_OK(result
)) {
2814 status
= rpccli_spoolss_SetJob(cli
, mem_ctx
,
2821 if (!W_ERROR_IS_OK(result
)) {
2826 if (is_valid_policy_hnd(&hnd
)) {
2827 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2833 /****************************************************************************
2834 ****************************************************************************/
2836 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2837 TALLOC_CTX
*mem_ctx
, int argc
,
2843 const char *printername
;
2844 struct policy_handle hnd
;
2845 uint32_t value_offered
= 0;
2846 const char *value_name
= NULL
;
2847 uint32_t value_needed
;
2848 enum winreg_Type type
;
2849 uint8_t *data
= NULL
;
2850 uint32_t data_offered
= 0;
2851 uint32_t data_needed
;
2854 printf("Usage: %s printername\n", argv
[0]);
2858 /* Open printer handle */
2860 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2862 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2864 SEC_FLAG_MAXIMUM_ALLOWED
,
2866 if (!W_ERROR_IS_OK(result
)) {
2870 /* Enumerate data */
2872 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2884 data_offered
= data_needed
;
2885 value_offered
= value_needed
;
2886 data
= talloc_zero_array(mem_ctx
, uint8_t, data_needed
);
2887 value_name
= talloc_zero_array(mem_ctx
, char, value_needed
);
2889 while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2891 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2902 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2903 struct regval_blob v
;
2904 fstrcpy(v
.valuename
, value_name
);
2906 v
.size
= data_offered
;
2908 display_reg_value(v
);
2912 if (W_ERROR_V(result
) == ERRnomoreitems
) {
2913 result
= W_ERROR(ERRsuccess
);
2917 if (is_valid_policy_hnd(&hnd
)) {
2918 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2924 /****************************************************************************
2925 ****************************************************************************/
2927 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2928 TALLOC_CTX
*mem_ctx
, int argc
,
2933 const char *printername
;
2934 struct policy_handle hnd
;
2936 struct spoolss_PrinterEnumValues
*info
;
2939 printf("Usage: %s printername <keyname>\n", argv
[0]);
2943 /* Open printer handle */
2945 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2947 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2949 SEC_FLAG_MAXIMUM_ALLOWED
,
2951 if (!W_ERROR_IS_OK(result
)) {
2955 /* Enumerate subkeys */
2957 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
2963 if (!W_ERROR_IS_OK(result
)) {
2967 for (i
=0; i
< count
; i
++) {
2968 display_printer_data(info
[i
].value_name
,
2971 info
[i
].data
->length
);
2975 if (is_valid_policy_hnd(&hnd
)) {
2976 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2982 /****************************************************************************
2983 ****************************************************************************/
2985 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
2986 TALLOC_CTX
*mem_ctx
, int argc
,
2990 const char *printername
;
2991 const char *keyname
= NULL
;
2992 struct policy_handle hnd
;
2993 const char **key_buffer
= NULL
;
2995 uint32_t offered
= 0;
2997 if (argc
< 2 || argc
> 4) {
2998 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3009 offered
= atoi(argv
[3]);
3012 /* Open printer handle */
3014 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3016 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3018 SEC_FLAG_MAXIMUM_ALLOWED
,
3020 if (!W_ERROR_IS_OK(result
)) {
3024 /* Enumerate subkeys */
3026 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3032 if (!W_ERROR_IS_OK(result
)) {
3036 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3037 printf("%s\n", key_buffer
[i
]);
3042 if (is_valid_policy_hnd(&hnd
)) {
3043 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3049 /****************************************************************************
3050 ****************************************************************************/
3052 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3053 TALLOC_CTX
*mem_ctx
, int argc
,
3056 const char *printername
;
3057 const char *clientname
;
3058 struct policy_handle hnd
;
3061 struct spoolss_NotifyOption option
;
3064 printf("Usage: %s printername\n", argv
[0]);
3071 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3073 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3075 SEC_FLAG_MAXIMUM_ALLOWED
,
3077 if (!W_ERROR_IS_OK(result
)) {
3078 printf("Error opening %s\n", argv
[1]);
3082 /* Create spool options */
3087 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3088 if (option
.types
== NULL
) {
3089 result
= WERR_NOMEM
;
3093 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3094 option
.types
[0].count
= 1;
3095 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3096 if (option
.types
[0].fields
== NULL
) {
3097 result
= WERR_NOMEM
;
3100 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3102 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3103 option
.types
[1].count
= 1;
3104 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3105 if (option
.types
[1].fields
== NULL
) {
3106 result
= WERR_NOMEM
;
3109 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3111 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
3113 result
= WERR_NOMEM
;
3119 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
3127 if (!W_ERROR_IS_OK(result
)) {
3128 printf("Error rffpcnex %s\n", argv
[1]);
3133 if (is_valid_policy_hnd(&hnd
))
3134 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3139 /****************************************************************************
3140 ****************************************************************************/
3142 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3143 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3145 union spoolss_PrinterInfo info1
, info2
;
3147 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3149 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3150 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3155 if ( !W_ERROR_IS_OK(werror
) ) {
3156 printf("failed (%s)\n", win_errstr(werror
));
3157 talloc_destroy(mem_ctx
);
3162 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3163 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3168 if ( !W_ERROR_IS_OK(werror
) ) {
3169 printf("failed (%s)\n", win_errstr(werror
));
3170 talloc_destroy(mem_ctx
);
3175 talloc_destroy(mem_ctx
);
3180 /****************************************************************************
3181 ****************************************************************************/
3183 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3184 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3186 union spoolss_PrinterInfo info1
, info2
;
3188 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3189 struct security_descriptor
*sd1
, *sd2
;
3193 printf("Retrieving printer security for %s...", cli1
->desthost
);
3194 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3199 if ( !W_ERROR_IS_OK(werror
) ) {
3200 printf("failed (%s)\n", win_errstr(werror
));
3206 printf("Retrieving printer security for %s...", cli2
->desthost
);
3207 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3212 if ( !W_ERROR_IS_OK(werror
) ) {
3213 printf("failed (%s)\n", win_errstr(werror
));
3222 sd1
= info1
.info3
.secdesc
;
3223 sd2
= info2
.info3
.secdesc
;
3225 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3226 printf("NULL secdesc!\n");
3231 if (!security_descriptor_equal( sd1
, sd2
) ) {
3232 printf("Security Descriptors *not* equal!\n");
3237 printf("Security descriptors match\n");
3240 talloc_destroy(mem_ctx
);
3245 /****************************************************************************
3246 ****************************************************************************/
3248 extern struct user_auth_info
*rpcclient_auth_info
;
3250 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3251 TALLOC_CTX
*mem_ctx
, int argc
,
3254 const char *printername
;
3255 char *printername_path
= NULL
;
3256 struct cli_state
*cli_server2
= NULL
;
3257 struct rpc_pipe_client
*cli2
= NULL
;
3258 struct policy_handle hPrinter1
, hPrinter2
;
3263 printf("Usage: %s <printer> <server>\n", argv
[0]);
3267 printername
= argv
[1];
3269 /* first get the connection to the remote server */
3271 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
3274 get_cmdline_auth_info_username(rpcclient_auth_info
),
3276 get_cmdline_auth_info_password(rpcclient_auth_info
),
3277 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3278 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
3280 if ( !NT_STATUS_IS_OK(nt_status
) )
3281 return WERR_GENERAL_FAILURE
;
3283 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
.syntax_id
,
3285 if (!NT_STATUS_IS_OK(nt_status
)) {
3286 printf("failed to open spoolss pipe on server %s (%s)\n",
3287 argv
[2], nt_errstr(nt_status
));
3288 return WERR_GENERAL_FAILURE
;
3291 /* now open up both printers */
3293 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3295 printf("Opening %s...", printername_path
);
3297 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3301 if ( !W_ERROR_IS_OK(werror
) ) {
3302 printf("failed (%s)\n", win_errstr(werror
));
3307 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3309 printf("Opening %s...", printername_path
);
3310 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3314 if ( !W_ERROR_IS_OK(werror
) ) {
3315 printf("failed (%s)\n", win_errstr(werror
));
3320 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3321 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3323 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3330 printf("Closing printers...");
3331 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3332 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3335 /* close the second remote connection */
3337 cli_shutdown( cli_server2
);
3341 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3343 printf("print_processor_name: %s\n", r
->print_processor_name
);
3346 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3347 TALLOC_CTX
*mem_ctx
, int argc
,
3351 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3352 uint32_t num_procs
, level
= 1, i
;
3353 union spoolss_PrintProcessorInfo
*procs
;
3355 /* Parse the command arguments */
3357 if (argc
< 1 || argc
> 4) {
3358 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3363 environment
= argv
[1];
3367 level
= atoi(argv
[2]);
3370 /* Enumerate Print Processors */
3372 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3373 cli
->srv_name_slash
,
3379 if (!W_ERROR_IS_OK(werror
))
3382 /* Display output */
3384 for (i
= 0; i
< num_procs
; i
++) {
3387 display_proc_info1(&procs
[i
].info1
);
3396 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3398 printf("name_array: %s\n", r
->name_array
);
3401 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3402 TALLOC_CTX
*mem_ctx
, int argc
,
3406 const char *print_processor_name
= "winprint";
3407 uint32_t num_procs
, level
= 1, i
;
3408 union spoolss_PrintProcDataTypesInfo
*procs
;
3410 /* Parse the command arguments */
3412 if (argc
< 1 || argc
> 4) {
3413 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3418 print_processor_name
= argv
[1];
3422 level
= atoi(argv
[2]);
3425 /* Enumerate Print Processor Data Types */
3427 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3428 cli
->srv_name_slash
,
3429 print_processor_name
,
3434 if (!W_ERROR_IS_OK(werror
))
3437 /* Display output */
3439 for (i
= 0; i
< num_procs
; i
++) {
3442 display_proc_data_types_info1(&procs
[i
].info1
);
3451 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3453 printf("monitor_name: %s\n", r
->monitor_name
);
3456 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3458 printf("monitor_name: %s\n", r
->monitor_name
);
3459 printf("environment: %s\n", r
->environment
);
3460 printf("dll_name: %s\n", r
->dll_name
);
3463 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3464 TALLOC_CTX
*mem_ctx
, int argc
,
3468 uint32_t count
, level
= 1, i
;
3469 union spoolss_MonitorInfo
*info
;
3471 /* Parse the command arguments */
3474 printf("Usage: %s [level]\n", argv
[0]);
3479 level
= atoi(argv
[1]);
3482 /* Enumerate Print Monitors */
3484 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3485 cli
->srv_name_slash
,
3490 if (!W_ERROR_IS_OK(werror
)) {
3494 /* Display output */
3496 for (i
= 0; i
< count
; i
++) {
3499 display_monitor1(&info
[i
].info1
);
3502 display_monitor2(&info
[i
].info2
);
3511 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3512 TALLOC_CTX
*mem_ctx
, int argc
,
3517 struct policy_handle handle
, gdi_handle
;
3518 const char *printername
;
3519 struct spoolss_DevmodeContainer devmode_ctr
;
3521 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3523 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3525 SEC_FLAG_MAXIMUM_ALLOWED
,
3527 if (!W_ERROR_IS_OK(result
)) {
3531 ZERO_STRUCT(devmode_ctr
);
3533 status
= rpccli_spoolss_CreatePrinterIC(cli
, mem_ctx
,
3538 if (!W_ERROR_IS_OK(result
)) {
3543 if (is_valid_policy_hnd(&gdi_handle
)) {
3544 rpccli_spoolss_DeletePrinterIC(cli
, mem_ctx
, &gdi_handle
, NULL
);
3546 if (is_valid_policy_hnd(&handle
)) {
3547 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
3553 /* List of commands exported by this module */
3554 struct cmd_set spoolss_commands
[] = {
3558 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a print driver", "" },
3559 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a printer", "" },
3560 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver", "" },
3561 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver with files", "" },
3562 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data", "" },
3563 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data for a key", "" },
3564 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer keys", "" },
3565 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate print jobs", "" },
3566 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print job", "" },
3567 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set print job", "" },
3568 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer ports", "" },
3569 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate installed printer drivers", "" },
3570 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printers", "" },
3571 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver data", "" },
3572 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer driver data with keyname", ""},
3573 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver information", "" },
3574 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver upload directory", "" },
3575 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer info", "" },
3576 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3577 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer driver", "" },
3578 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print processor directory", "" },
3579 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add form", "" },
3580 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set form", "" },
3581 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get form", "" },
3582 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete form", "" },
3583 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate forms", "" },
3584 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer comment", "" },
3585 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printername", "" },
3586 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set REG_SZ printer data", "" },
3587 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Rffpcnex test", "" },
3588 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
.syntax_id
, NULL
, "Printer comparison test", "" },
3589 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processors", "" },
3590 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processor Data Types", "" },
3591 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Monitors", "" },
3592 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
.syntax_id
, NULL
, "Create Printer IC", "" },