2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "rpcclient.h"
27 #include "../librpc/gen_ndr/cli_spoolss.h"
29 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
31 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
32 _cli->srv_name_slash, _arg); \
33 W_ERROR_HAVE_NO_MEMORY(_printername); \
36 /* The version int is used by getdrivers. Note that
37 all architecture strings that support mutliple
38 versions must be grouped together since enumdrivers
39 uses this property to prevent issuing multiple
40 enumdriver calls for the same arch */
43 static const struct print_architecture_table_node archi_table
[]= {
45 {"Windows 4.0", "WIN40", 0 },
46 {"Windows NT x86", "W32X86", 2 },
47 {"Windows NT x86", "W32X86", 3 },
48 {"Windows NT R4000", "W32MIPS", 2 },
49 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
50 {"Windows NT PowerPC", "W32PPC", 2 },
51 {"Windows IA64", "IA64", 3 },
52 {"Windows x64", "x64", 3 },
59 * rpcclient module for SPOOLSS rpc pipe.
61 * This generally just parses and checks command lines, and then calls
62 * a cli_spoolss function.
65 /****************************************************************************
66 function to do the mapping between the long architecture name and
68 ****************************************************************************/
70 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
74 DEBUG(107,("Getting architecture dependant directory\n"));
77 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
78 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
80 if (archi_table
[i
].long_archi
==NULL
) {
81 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
85 /* this might be client code - but shouldn't this be an fstrcpy etc? */
88 DEBUGADD(108,("index: [%d]\n", i
));
89 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
90 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
92 return archi_table
[i
].short_archi
;
95 /****************************************************************************
96 ****************************************************************************/
98 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
100 int argc
, const char **argv
)
103 struct policy_handle hnd
;
106 printf("Usage: %s <printername>\n", argv
[0]);
111 return WERR_GENERAL_FAILURE
;
113 /* Open the printer handle */
115 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
119 if (W_ERROR_IS_OK(werror
)) {
120 printf("Printer %s opened successfully\n", argv
[1]);
121 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
123 if (!W_ERROR_IS_OK(werror
)) {
124 printf("Error closing printer handle! (%s)\n",
125 get_dos_error_msg(werror
));
133 /****************************************************************************
134 ****************************************************************************/
136 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
141 printf("\tprintername:[%s]\n", r
->printername
);
142 printf("\tservername:[%s]\n", r
->servername
);
143 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
144 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
145 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
146 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
147 r
->time
.day
, r
->time
.day_of_week
);
148 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
149 r
->time
.second
, r
->time
.millisecond
);
151 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
152 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
154 printf("\tversion:[0x%x]\n", r
->version
);
155 printf("\tfree_build:[0x%x]\n", r
->free_build
);
156 printf("\tspooling:[0x%x]\n", r
->spooling
);
157 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
158 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
159 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
160 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
161 printf("\tjob_error:[0x%x]\n", r
->job_error
);
162 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
163 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
164 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
165 printf("\tchange_id:[0x%x]\n", r
->change_id
);
166 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
167 printf("\tstatus:[0x%x]\n", r
->status
);
168 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
169 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
170 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
171 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
172 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
173 printf("\treserved2:[0x%x]\n", r
->reserved2
);
174 printf("\treserved3:[0x%x]\n", r
->reserved3
);
179 /****************************************************************************
180 ****************************************************************************/
182 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
184 printf("\tflags:[0x%x]\n", r
->flags
);
185 printf("\tname:[%s]\n", r
->name
);
186 printf("\tdescription:[%s]\n", r
->description
);
187 printf("\tcomment:[%s]\n", r
->comment
);
192 /****************************************************************************
193 ****************************************************************************/
195 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
197 printf("\tservername:[%s]\n", r
->servername
);
198 printf("\tprintername:[%s]\n", r
->printername
);
199 printf("\tsharename:[%s]\n", r
->sharename
);
200 printf("\tportname:[%s]\n", r
->portname
);
201 printf("\tdrivername:[%s]\n", r
->drivername
);
202 printf("\tcomment:[%s]\n", r
->comment
);
203 printf("\tlocation:[%s]\n", r
->location
);
204 printf("\tsepfile:[%s]\n", r
->sepfile
);
205 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
206 printf("\tdatatype:[%s]\n", r
->datatype
);
207 printf("\tparameters:[%s]\n", r
->parameters
);
208 printf("\tattributes:[0x%x]\n", r
->attributes
);
209 printf("\tpriority:[0x%x]\n", r
->priority
);
210 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
211 printf("\tstarttime:[0x%x]\n", r
->starttime
);
212 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
213 printf("\tstatus:[0x%x]\n", r
->status
);
214 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
215 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
218 display_sec_desc(r
->secdesc
);
223 /****************************************************************************
224 ****************************************************************************/
226 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
228 display_sec_desc(r
->secdesc
);
233 /****************************************************************************
234 ****************************************************************************/
236 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
238 printf("\tservername:[%s]\n", r
->servername
);
239 printf("\tprintername:[%s]\n", r
->printername
);
240 printf("\tattributes:[0x%x]\n", r
->attributes
);
244 /****************************************************************************
245 ****************************************************************************/
247 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
249 printf("\tprintername:[%s]\n", r
->printername
);
250 printf("\tportname:[%s]\n", r
->portname
);
251 printf("\tattributes:[0x%x]\n", r
->attributes
);
252 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
253 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
257 /****************************************************************************
258 ****************************************************************************/
260 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
262 printf("\tstatus:[0x%x]\n", r
->status
);
266 /****************************************************************************
267 ****************************************************************************/
269 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
271 printf("\tguid:[%s]\n", r
->guid
);
272 printf("\taction:[0x%x]\n", r
->action
);
276 /****************************************************************************
277 ****************************************************************************/
279 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
281 int argc
, const char **argv
)
285 union spoolss_PrinterInfo
*info
;
288 uint32_t flags
= PRINTER_ENUM_LOCAL
;
291 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
296 level
= atoi(argv
[1]);
302 name
= cli
->srv_name_slash
;
306 flags
= atoi(argv
[3]);
309 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
316 if (W_ERROR_IS_OK(result
)) {
319 printf ("No printers returned.\n");
323 for (i
= 0; i
< count
; i
++) {
326 display_print_info0(&info
[i
].info0
);
329 display_print_info1(&info
[i
].info1
);
332 display_print_info2(&info
[i
].info2
);
335 display_print_info3(&info
[i
].info3
);
338 display_print_info4(&info
[i
].info4
);
341 display_print_info5(&info
[i
].info5
);
344 display_print_info6(&info
[i
].info6
);
347 printf("unknown info level %d\n", level
);
357 /****************************************************************************
358 ****************************************************************************/
360 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
362 printf("\tPort Name:\t[%s]\n", r
->port_name
);
365 /****************************************************************************
366 ****************************************************************************/
368 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
370 printf("\tPort Name:\t[%s]\n", r
->port_name
);
371 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
372 printf("\tDescription:\t[%s]\n", r
->description
);
373 printf("\tPort Type:\t" );
375 int comma
= 0; /* hack */
377 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
381 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
382 printf( "%sWrite", comma
? ", " : "" );
385 /* These two have slightly different interpretations
386 on 95/98/ME but I'm disregarding that for now */
387 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
388 printf( "%sRedirected", comma
? ", " : "" );
391 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
392 printf( "%sNet-Attached", comma
? ", " : "" );
396 printf( "[Unset]\n" );
398 printf("\tReserved:\t[%d]\n", r
->reserved
);
402 /****************************************************************************
403 ****************************************************************************/
405 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
406 TALLOC_CTX
*mem_ctx
, int argc
,
412 union spoolss_PortInfo
*info
;
415 printf("Usage: %s [level]\n", argv
[0]);
420 level
= atoi(argv
[1]);
423 /* Enumerate ports */
425 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
431 if (W_ERROR_IS_OK(result
)) {
434 for (i
= 0; i
< count
; i
++) {
437 display_port_info_1(&info
[i
].info1
);
440 display_port_info_2(&info
[i
].info2
);
443 printf("unknown info level %d\n", level
);
452 /****************************************************************************
453 ****************************************************************************/
455 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
457 int argc
, const char **argv
)
459 struct policy_handle pol
;
462 uint32_t info_level
= 2;
463 union spoolss_PrinterInfo info
;
464 struct spoolss_SetPrinterInfoCtr info_ctr
;
465 struct spoolss_SetPrinterInfo2 info2
;
466 const char *printername
, *comment
= NULL
;
467 struct spoolss_DevmodeContainer devmode_ctr
;
468 struct sec_desc_buf secdesc_ctr
;
470 if (argc
== 1 || argc
> 3) {
471 printf("Usage: %s printername comment\n", argv
[0]);
476 /* Open a printer handle */
481 ZERO_STRUCT(devmode_ctr
);
482 ZERO_STRUCT(secdesc_ctr
);
484 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
486 /* get a printer handle */
487 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
491 if (!W_ERROR_IS_OK(result
))
494 /* Get printer info */
495 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
500 if (!W_ERROR_IS_OK(result
))
504 /* Modify the comment. */
505 info2
.servername
= info
.info2
.servername
;
506 info2
.printername
= info
.info2
.printername
;
507 info2
.sharename
= info
.info2
.sharename
;
508 info2
.portname
= info
.info2
.portname
;
509 info2
.drivername
= info
.info2
.drivername
;
510 info2
.comment
= comment
;
511 info2
.location
= info
.info2
.location
;
512 info2
.devmode_ptr
= 0;
513 info2
.sepfile
= info
.info2
.sepfile
;
514 info2
.printprocessor
= info
.info2
.printprocessor
;
515 info2
.datatype
= info
.info2
.datatype
;
516 info2
.parameters
= info
.info2
.parameters
;
517 info2
.secdesc_ptr
= 0;
518 info2
.attributes
= info
.info2
.attributes
;
519 info2
.priority
= info
.info2
.priority
;
520 info2
.defaultpriority
= info
.info2
.defaultpriority
;
521 info2
.starttime
= info
.info2
.starttime
;
522 info2
.untiltime
= info
.info2
.untiltime
;
523 info2
.status
= info
.info2
.status
;
524 info2
.cjobs
= info
.info2
.cjobs
;
525 info2
.averageppm
= info
.info2
.averageppm
;
528 info_ctr
.info
.info2
= &info2
;
530 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
537 if (W_ERROR_IS_OK(result
))
538 printf("Success in setting comment.\n");
541 if (is_valid_policy_hnd(&pol
))
542 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
547 /****************************************************************************
548 ****************************************************************************/
550 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
552 int argc
, const char **argv
)
554 struct policy_handle pol
;
557 uint32_t info_level
= 2;
558 union spoolss_PrinterInfo info
;
559 const char *printername
,
560 *new_printername
= NULL
;
561 struct spoolss_SetPrinterInfoCtr info_ctr
;
562 struct spoolss_SetPrinterInfo2 info2
;
563 struct spoolss_DevmodeContainer devmode_ctr
;
564 struct sec_desc_buf secdesc_ctr
;
566 ZERO_STRUCT(devmode_ctr
);
567 ZERO_STRUCT(secdesc_ctr
);
569 if (argc
== 1 || argc
> 3) {
570 printf("Usage: %s printername new_printername\n", argv
[0]);
575 /* Open a printer handle */
577 new_printername
= argv
[2];
580 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
582 /* get a printer handle */
583 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
587 if (!W_ERROR_IS_OK(result
))
590 /* Get printer info */
591 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
596 if (!W_ERROR_IS_OK(result
))
599 /* Modify the printername. */
600 info2
.servername
= info
.info2
.servername
;
601 info2
.printername
= new_printername
;
602 info2
.sharename
= info
.info2
.sharename
;
603 info2
.portname
= info
.info2
.portname
;
604 info2
.drivername
= info
.info2
.drivername
;
605 info2
.comment
= info
.info2
.comment
;
606 info2
.location
= info
.info2
.location
;
607 info2
.devmode_ptr
= 0;
608 info2
.sepfile
= info
.info2
.sepfile
;
609 info2
.printprocessor
= info
.info2
.printprocessor
;
610 info2
.datatype
= info
.info2
.datatype
;
611 info2
.parameters
= info
.info2
.parameters
;
612 info2
.secdesc_ptr
= 0;
613 info2
.attributes
= info
.info2
.attributes
;
614 info2
.priority
= info
.info2
.priority
;
615 info2
.defaultpriority
= info
.info2
.defaultpriority
;
616 info2
.starttime
= info
.info2
.starttime
;
617 info2
.untiltime
= info
.info2
.untiltime
;
618 info2
.status
= info
.info2
.status
;
619 info2
.cjobs
= info
.info2
.cjobs
;
620 info2
.averageppm
= info
.info2
.averageppm
;
623 info_ctr
.info
.info2
= &info2
;
625 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
632 if (W_ERROR_IS_OK(result
))
633 printf("Success in setting printername.\n");
636 if (is_valid_policy_hnd(&pol
))
637 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
642 /****************************************************************************
643 ****************************************************************************/
645 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
647 int argc
, const char **argv
)
649 struct policy_handle pol
;
652 const char *printername
;
653 union spoolss_PrinterInfo info
;
655 if (argc
== 1 || argc
> 3) {
656 printf("Usage: %s <printername> [level]\n", argv
[0]);
660 /* Open a printer handle */
662 level
= atoi(argv
[2]);
665 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
667 /* get a printer handle */
669 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
671 SEC_FLAG_MAXIMUM_ALLOWED
,
673 if (!W_ERROR_IS_OK(result
)) {
677 /* Get printer info */
679 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
684 if (!W_ERROR_IS_OK(result
)) {
688 /* Display printer info */
691 display_print_info0(&info
.info0
);
694 display_print_info1(&info
.info1
);
697 display_print_info2(&info
.info2
);
700 display_print_info3(&info
.info3
);
703 display_print_info4(&info
.info4
);
706 display_print_info5(&info
.info5
);
709 display_print_info6(&info
.info6
);
712 display_print_info7(&info
.info7
);
715 printf("unknown info level %d\n", level
);
719 if (is_valid_policy_hnd(&pol
)) {
720 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
726 /****************************************************************************
727 ****************************************************************************/
729 static void display_reg_value(struct regval_blob value
)
731 const char *text
= NULL
;
736 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
737 *((uint32_t *) value
.data_p
));
740 blob
= data_blob_const(value
.data_p
, value
.size
);
741 pull_reg_sz(talloc_tos(), NULL
, &blob
, &text
);
742 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
745 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
747 printf("%s: REG_BINARY:", value
.valuename
);
749 for (i
=0; i
<len
; i
++) {
750 if (hex
[i
] == '\0') {
765 blob
= data_blob_const(value
.data_p
, value
.size
);
767 if (!pull_reg_multi_sz(NULL
, NULL
, &blob
, &values
)) {
768 d_printf("pull_reg_multi_sz failed\n");
772 printf("%s: REG_MULTI_SZ: \n", value
.valuename
);
773 for (i
=0; values
[i
] != NULL
; i
++) {
774 d_printf("%s\n", values
[i
]);
780 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
785 /****************************************************************************
786 ****************************************************************************/
788 static void display_printer_data(const char *v
,
789 enum winreg_Type type
,
794 union spoolss_PrinterData r
;
795 DATA_BLOB blob
= data_blob_const(data
, length
);
798 result
= pull_spoolss_PrinterData(talloc_tos(), &blob
, &r
, type
);
799 if (!W_ERROR_IS_OK(result
)) {
805 printf("%s: REG_DWORD: 0x%08x\n", v
, r
.value
);
808 printf("%s: REG_SZ: %s\n", v
, r
.string
);
811 char *hex
= hex_encode_talloc(NULL
,
812 r
.binary
.data
, r
.binary
.length
);
814 printf("%s: REG_BINARY:", v
);
816 for (i
=0; i
<len
; i
++) {
817 if (hex
[i
] == '\0') {
830 printf("%s: REG_MULTI_SZ: ", v
);
831 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
832 printf("%s ", r
.string_array
[i
]);
837 printf("%s: unknown type 0x%02x:\n", v
, type
);
842 /****************************************************************************
843 ****************************************************************************/
845 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
847 int argc
, const char **argv
)
849 struct policy_handle pol
;
852 const char *valuename
;
853 enum winreg_Type type
;
858 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
859 printf("<printername> of . queries print server\n");
864 /* Open a printer handle */
866 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
867 fstrcpy(printername
, cli
->srv_name_slash
);
869 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
870 cli
->srv_name_slash
, argv
[1]);
872 /* get a printer handle */
874 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
876 SEC_FLAG_MAXIMUM_ALLOWED
,
878 if (!W_ERROR_IS_OK(result
))
881 /* Get printer info */
883 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
890 if (!W_ERROR_IS_OK(result
))
893 /* Display printer data */
895 display_printer_data(valuename
, type
, data
, needed
);
898 if (is_valid_policy_hnd(&pol
))
899 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
904 /****************************************************************************
905 ****************************************************************************/
907 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
909 int argc
, const char **argv
)
911 struct policy_handle pol
;
915 const char *valuename
, *keyname
;
917 enum winreg_Type type
;
918 uint8_t *data
= NULL
;
919 uint32_t offered
= 0;
923 printf("Usage: %s <printername> <keyname> <valuename>\n",
925 printf("<printername> of . queries print server\n");
931 /* Open a printer handle */
933 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
934 fstrcpy(printername
, cli
->srv_name_slash
);
936 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
937 cli
->srv_name_slash
, argv
[1]);
939 /* get a printer handle */
941 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
943 SEC_FLAG_MAXIMUM_ALLOWED
,
945 if (!W_ERROR_IS_OK(result
))
948 /* Get printer info */
950 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
955 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
964 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
966 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
970 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
981 if (!NT_STATUS_IS_OK(status
)) {
985 if (!W_ERROR_IS_OK(result
))
988 /* Display printer data */
990 display_printer_data(valuename
, type
, data
, needed
);
994 if (is_valid_policy_hnd(&pol
))
995 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1000 /****************************************************************************
1001 ****************************************************************************/
1003 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1009 printf("Printer Driver Info 1:\n");
1010 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1014 /****************************************************************************
1015 ****************************************************************************/
1017 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1023 printf("Printer Driver Info 2:\n");
1024 printf("\tVersion: [%x]\n", r
->version
);
1025 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1026 printf("\tArchitecture: [%s]\n", r
->architecture
);
1027 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1028 printf("\tDatafile: [%s]\n", r
->data_file
);
1029 printf("\tConfigfile: [%s]\n", r
->config_file
);
1033 /****************************************************************************
1034 ****************************************************************************/
1036 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1044 printf("Printer Driver Info 3:\n");
1045 printf("\tVersion: [%x]\n", r
->version
);
1046 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1047 printf("\tArchitecture: [%s]\n", r
->architecture
);
1048 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1049 printf("\tDatafile: [%s]\n", r
->data_file
);
1050 printf("\tConfigfile: [%s]\n", r
->config_file
);
1051 printf("\tHelpfile: [%s]\n", r
->help_file
);
1053 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1054 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1057 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1058 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1062 /****************************************************************************
1063 ****************************************************************************/
1065 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1073 printf("Printer Driver Info 4:\n");
1074 printf("\tVersion: [%x]\n", r
->version
);
1075 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1076 printf("\tArchitecture: [%s]\n", r
->architecture
);
1077 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1078 printf("\tDatafile: [%s]\n", r
->data_file
);
1079 printf("\tConfigfile: [%s]\n", r
->config_file
);
1080 printf("\tHelpfile: [%s]\n", r
->help_file
);
1082 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1083 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1086 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1087 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1089 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1090 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1095 /****************************************************************************
1096 ****************************************************************************/
1098 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1104 printf("Printer Driver Info 5:\n");
1105 printf("\tVersion: [%x]\n", r
->version
);
1106 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1107 printf("\tArchitecture: [%s]\n", r
->architecture
);
1108 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1109 printf("\tDatafile: [%s]\n", r
->data_file
);
1110 printf("\tConfigfile: [%s]\n", r
->config_file
);
1111 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1112 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1113 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1117 /****************************************************************************
1118 ****************************************************************************/
1120 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1128 printf("Printer Driver Info 6:\n");
1129 printf("\tVersion: [%x]\n", r
->version
);
1130 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1131 printf("\tArchitecture: [%s]\n", r
->architecture
);
1132 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1133 printf("\tDatafile: [%s]\n", r
->data_file
);
1134 printf("\tConfigfile: [%s]\n", r
->config_file
);
1135 printf("\tHelpfile: [%s]\n", r
->help_file
);
1137 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1138 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1141 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1142 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1144 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1145 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1148 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1149 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1150 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1151 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1152 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1153 printf("\tProvider: [%s]\n", r
->provider
);
1158 /****************************************************************************
1159 ****************************************************************************/
1161 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1169 printf("Printer Driver Info 8:\n");
1170 printf("\tVersion: [%x]\n", r
->version
);
1171 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1172 printf("\tArchitecture: [%s]\n", r
->architecture
);
1173 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1174 printf("\tDatafile: [%s]\n", r
->data_file
);
1175 printf("\tConfigfile: [%s]\n", r
->config_file
);
1176 printf("\tHelpfile: [%s]\n", r
->help_file
);
1177 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1178 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1180 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1181 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1184 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1185 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1188 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1189 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1190 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1191 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1192 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1193 printf("\tProvider: [%s]\n", r
->provider
);
1194 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1195 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1196 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1197 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1199 printf("\tInf Path: [%s]\n", r
->inf_path
);
1200 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1201 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1202 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1204 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1205 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1206 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1211 /****************************************************************************
1212 ****************************************************************************/
1214 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1215 TALLOC_CTX
*mem_ctx
,
1216 int argc
, const char **argv
)
1218 struct policy_handle pol
;
1221 const char *printername
;
1223 bool success
= false;
1224 union spoolss_DriverInfo info
;
1225 uint32_t server_major_version
;
1226 uint32_t server_minor_version
;
1228 if ((argc
== 1) || (argc
> 3)) {
1229 printf("Usage: %s <printername> [level]\n", argv
[0]);
1233 /* get the arguments need to open the printer handle */
1235 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1238 level
= atoi(argv
[2]);
1241 /* Open a printer handle */
1243 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1247 if (!W_ERROR_IS_OK(werror
)) {
1248 printf("Error opening printer handle for %s!\n", printername
);
1252 /* loop through and print driver info level for each architecture */
1254 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1256 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1258 archi_table
[i
].long_archi
,
1261 archi_table
[i
].version
,
1264 &server_major_version
,
1265 &server_minor_version
);
1266 if (!W_ERROR_IS_OK(werror
)) {
1270 /* need at least one success */
1274 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1278 display_print_driver1(&info
.info1
);
1281 display_print_driver2(&info
.info2
);
1284 display_print_driver3(&info
.info3
);
1287 display_print_driver4(&info
.info4
);
1290 display_print_driver5(&info
.info5
);
1293 display_print_driver6(&info
.info6
);
1296 display_print_driver8(&info
.info8
);
1299 printf("unknown info level %d\n", level
);
1306 if (is_valid_policy_hnd(&pol
)) {
1307 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1317 /****************************************************************************
1318 ****************************************************************************/
1320 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1321 TALLOC_CTX
*mem_ctx
,
1322 const char *architecture
,
1327 union spoolss_DriverInfo
*info
= NULL
;
1330 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1331 cli
->srv_name_slash
,
1338 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1339 printf("Server does not support environment [%s]\n",
1348 if (!W_ERROR_IS_OK(werror
)) {
1349 printf("Error getting driver for environment [%s] - %s\n",
1350 architecture
, win_errstr(werror
));
1354 printf("\n[%s]\n", architecture
);
1358 for (j
=0; j
< count
; j
++) {
1359 display_print_driver1(&info
[j
].info1
);
1363 for (j
=0; j
< count
; j
++) {
1364 display_print_driver2(&info
[j
].info2
);
1368 for (j
=0; j
< count
; j
++) {
1369 display_print_driver3(&info
[j
].info3
);
1373 for (j
=0; j
< count
; j
++) {
1374 display_print_driver4(&info
[j
].info4
);
1378 for (j
=0; j
< count
; j
++) {
1379 display_print_driver5(&info
[j
].info5
);
1383 for (j
=0; j
< count
; j
++) {
1384 display_print_driver6(&info
[j
].info6
);
1388 for (j
=0; j
< count
; j
++) {
1389 display_print_driver8(&info
[j
].info8
);
1393 printf("unknown info level %d\n", level
);
1394 return WERR_UNKNOWN_LEVEL
;
1400 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1401 TALLOC_CTX
*mem_ctx
,
1402 int argc
, const char **argv
)
1404 WERROR werror
= WERR_OK
;
1407 const char *architecture
= NULL
;
1410 printf("Usage: enumdrivers [level] [architecture]\n");
1415 level
= atoi(argv
[1]);
1419 architecture
= argv
[2];
1423 return enum_driver_by_architecture(cli
, mem_ctx
,
1428 /* loop through and print driver info level for each architecture */
1429 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1430 /* check to see if we already asked for this architecture string */
1432 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1436 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1437 archi_table
[i
].long_archi
,
1439 if (!W_ERROR_IS_OK(werror
)) {
1447 /****************************************************************************
1448 ****************************************************************************/
1450 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1452 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1455 /****************************************************************************
1456 ****************************************************************************/
1458 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1459 TALLOC_CTX
*mem_ctx
,
1460 int argc
, const char **argv
)
1464 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1467 union spoolss_DriverDirectoryInfo info
;
1471 printf("Usage: %s [environment]\n", argv
[0]);
1475 /* Get the arguments need to open the printer handle */
1481 /* Get the directory. Only use Info level 1 */
1483 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1484 cli
->srv_name_slash
,
1492 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1494 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1496 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1497 cli
->srv_name_slash
,
1507 if (W_ERROR_IS_OK(result
)) {
1508 display_printdriverdir_1(&info
.info1
);
1514 /****************************************************************************
1515 ****************************************************************************/
1517 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1518 struct spoolss_AddDriverInfo3
*info
,
1524 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1526 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1528 info
->version
= archi_table
[i
].version
;
1529 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1534 if (archi_table
[i
].long_archi
== NULL
)
1536 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1543 /**************************************************************************
1544 wrapper for strtok to get the next parameter from a delimited list.
1545 Needed to handle the empty parameter string denoted by "NULL"
1546 *************************************************************************/
1548 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1549 const char *delim
, const char **dest
,
1554 /* get the next token */
1555 ptr
= strtok_r(str
, delim
, saveptr
);
1557 /* a string of 'NULL' is used to represent an empty
1558 parameter because two consecutive delimiters
1559 will not return an empty string. See man strtok(3)
1561 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1566 *dest
= talloc_strdup(mem_ctx
, ptr
);
1572 /********************************************************************************
1573 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1574 string in the form of
1575 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1576 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1577 <Default Data Type>:<Comma Separated list of Files>
1578 *******************************************************************************/
1580 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1585 char *saveptr
= NULL
;
1586 struct spoolss_StringArray
*deps
;
1587 const char **file_array
= NULL
;
1590 /* fill in the UNISTR fields */
1591 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1592 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1593 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1594 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1595 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1596 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1597 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1599 /* <Comma Separated List of Dependent Files> */
1600 /* save the beginning of the string */
1601 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1604 /* begin to strip out each filename */
1605 str
= strtok_r(str
, ",", &saveptr
);
1607 /* no dependent files, we are done */
1612 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1617 while (str
!= NULL
) {
1618 add_string_to_array(deps
, str
, &file_array
, &count
);
1619 str
= strtok_r(NULL
, ",", &saveptr
);
1622 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1623 if (!deps
->string
) {
1627 for (i
=0; i
< count
; i
++) {
1628 deps
->string
[i
] = file_array
[i
];
1631 r
->dependent_files
= deps
;
1636 /****************************************************************************
1637 ****************************************************************************/
1639 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1640 TALLOC_CTX
*mem_ctx
,
1641 int argc
, const char **argv
)
1646 struct spoolss_AddDriverInfoCtr info_ctr
;
1647 struct spoolss_AddDriverInfo3 info3
;
1651 /* parse the command arguments */
1652 if (argc
!= 3 && argc
!= 4)
1654 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1655 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1656 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1657 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1658 printf ("\t[version]\n");
1663 /* Fill in the spoolss_AddDriverInfo3 struct */
1666 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1668 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1669 return WERR_INVALID_PARAM
;
1672 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1674 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1675 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1677 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1678 return WERR_INVALID_PARAM
;
1681 /* if printer driver version specified, override the default version
1682 * used by the architecture. This allows installation of Windows
1683 * 2000 (version 3) printer drivers. */
1686 info3
.version
= atoi(argv
[3]);
1690 info_ctr
.level
= level
;
1691 info_ctr
.info
.info3
= &info3
;
1693 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1694 cli
->srv_name_slash
,
1697 if (!NT_STATUS_IS_OK(status
)) {
1698 return ntstatus_to_werror(status
);
1700 if (W_ERROR_IS_OK(result
)) {
1701 printf ("Printer Driver %s successfully installed.\n",
1709 /****************************************************************************
1710 ****************************************************************************/
1712 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1713 TALLOC_CTX
*mem_ctx
,
1714 int argc
, const char **argv
)
1717 struct spoolss_SetPrinterInfoCtr info_ctr
;
1718 struct spoolss_SetPrinterInfo2 info2
;
1720 /* parse the command arguments */
1723 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1727 /* Fill in the DRIVER_INFO_2 struct */
1730 info2
.printername
= argv
[1];
1731 info2
.drivername
= argv
[3];
1732 info2
.sharename
= argv
[2];
1733 info2
.portname
= argv
[4];
1734 info2
.comment
= "Created by rpcclient";
1735 info2
.printprocessor
= "winprint";
1736 info2
.datatype
= "RAW";
1737 info2
.devmode_ptr
= 0;
1738 info2
.secdesc_ptr
= 0;
1739 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1741 info2
.defaultpriority
= 0;
1742 info2
.starttime
= 0;
1743 info2
.untiltime
= 0;
1745 /* These three fields must not be used by AddPrinter()
1746 as defined in the MS Platform SDK documentation..
1750 info2.averageppm = 0;
1754 info_ctr
.info
.info2
= &info2
;
1756 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1758 if (W_ERROR_IS_OK(result
))
1759 printf ("Printer %s successfully installed.\n", argv
[1]);
1764 /****************************************************************************
1765 ****************************************************************************/
1767 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1768 TALLOC_CTX
*mem_ctx
,
1769 int argc
, const char **argv
)
1771 struct policy_handle pol
;
1775 const char *printername
;
1776 union spoolss_PrinterInfo info
;
1777 struct spoolss_SetPrinterInfoCtr info_ctr
;
1778 struct spoolss_SetPrinterInfo2 info2
;
1779 struct spoolss_DevmodeContainer devmode_ctr
;
1780 struct sec_desc_buf secdesc_ctr
;
1782 ZERO_STRUCT(devmode_ctr
);
1783 ZERO_STRUCT(secdesc_ctr
);
1785 /* parse the command arguments */
1788 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1792 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1794 /* Get a printer handle */
1796 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1800 if (!W_ERROR_IS_OK(result
))
1803 /* Get printer info */
1805 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1810 if (!W_ERROR_IS_OK(result
)) {
1811 printf ("Unable to retrieve printer information!\n");
1815 /* Set the printer driver */
1817 info2
.servername
= info
.info2
.servername
;
1818 info2
.printername
= info
.info2
.printername
;
1819 info2
.sharename
= info
.info2
.sharename
;
1820 info2
.portname
= info
.info2
.portname
;
1821 info2
.drivername
= argv
[2];
1822 info2
.comment
= info
.info2
.comment
;
1823 info2
.location
= info
.info2
.location
;
1824 info2
.devmode_ptr
= 0;
1825 info2
.sepfile
= info
.info2
.sepfile
;
1826 info2
.printprocessor
= info
.info2
.printprocessor
;
1827 info2
.datatype
= info
.info2
.datatype
;
1828 info2
.parameters
= info
.info2
.parameters
;
1829 info2
.secdesc_ptr
= 0;
1830 info2
.attributes
= info
.info2
.attributes
;
1831 info2
.priority
= info
.info2
.priority
;
1832 info2
.defaultpriority
= info
.info2
.defaultpriority
;
1833 info2
.starttime
= info
.info2
.starttime
;
1834 info2
.untiltime
= info
.info2
.untiltime
;
1835 info2
.status
= info
.info2
.status
;
1836 info2
.cjobs
= info
.info2
.cjobs
;
1837 info2
.averageppm
= info
.info2
.averageppm
;
1840 info_ctr
.info
.info2
= &info2
;
1842 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1849 if (!W_ERROR_IS_OK(result
)) {
1850 printf("SetPrinter call failed!\n");
1854 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1859 if (is_valid_policy_hnd(&pol
))
1860 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1866 /****************************************************************************
1867 ****************************************************************************/
1869 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1870 TALLOC_CTX
*mem_ctx
,
1871 int argc
, const char **argv
)
1873 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1879 const char *arch
= NULL
;
1880 uint32_t delete_flags
= 0;
1882 /* parse the command arguments */
1883 if (argc
< 2 || argc
> 4) {
1884 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1891 vers
= atoi (argv
[3]);
1894 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1897 /* delete the driver for all architectures */
1898 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1900 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1903 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1906 /* make the call to remove the driver */
1907 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1908 cli
->srv_name_slash
,
1909 archi_table
[i
].long_archi
,
1912 archi_table
[i
].version
,
1915 if ( !W_ERROR_IS_OK(result
) )
1917 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1918 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1919 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1924 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1925 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1934 /****************************************************************************
1935 ****************************************************************************/
1937 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1938 TALLOC_CTX
*mem_ctx
,
1939 int argc
, const char **argv
)
1941 WERROR result
= WERR_OK
;
1945 /* parse the command arguments */
1947 printf ("Usage: %s <driver>\n", argv
[0]);
1951 /* delete the driver for all architectures */
1952 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1953 /* make the call to remove the driver */
1954 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1955 cli
->srv_name_slash
,
1956 archi_table
[i
].long_archi
,
1959 if (!NT_STATUS_IS_OK(status
)) {
1962 if ( !W_ERROR_IS_OK(result
) ) {
1963 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1964 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1965 argv
[1], archi_table
[i
].long_archi
,
1969 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1970 archi_table
[i
].long_archi
);
1977 /****************************************************************************
1978 ****************************************************************************/
1980 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1981 TALLOC_CTX
*mem_ctx
,
1982 int argc
, const char **argv
)
1986 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1989 union spoolss_PrintProcessorDirectoryInfo info
;
1992 /* parse the command arguments */
1994 printf ("Usage: %s [environment]\n", argv
[0]);
1999 environment
= argv
[1];
2002 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
2003 cli
->srv_name_slash
,
2011 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2013 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2015 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
2016 cli
->srv_name_slash
,
2026 if (W_ERROR_IS_OK(result
)) {
2027 printf("%s\n", info
.info1
.directory_name
);
2033 /****************************************************************************
2034 ****************************************************************************/
2036 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2037 int argc
, const char **argv
)
2039 struct policy_handle handle
;
2042 const char *printername
;
2043 union spoolss_AddFormInfo info
;
2044 struct spoolss_AddFormInfo1 info1
;
2045 struct spoolss_AddFormInfo2 info2
;
2048 /* Parse the command arguments */
2050 if (argc
< 3 || argc
> 5) {
2051 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2055 /* Get a printer handle */
2057 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2059 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2063 if (!W_ERROR_IS_OK(werror
))
2066 /* Dummy up some values for the form data */
2069 level
= atoi(argv
[3]);
2074 info1
.flags
= SPOOLSS_FORM_USER
;
2075 info1
.form_name
= argv
[2];
2076 info1
.size
.width
= 100;
2077 info1
.size
.height
= 100;
2078 info1
.area
.left
= 0;
2079 info1
.area
.top
= 10;
2080 info1
.area
.right
= 20;
2081 info1
.area
.bottom
= 30;
2083 info
.info1
= &info1
;
2087 info2
.flags
= SPOOLSS_FORM_USER
;
2088 info2
.form_name
= argv
[2];
2089 info2
.size
.width
= 100;
2090 info2
.size
.height
= 100;
2091 info2
.area
.left
= 0;
2092 info2
.area
.top
= 10;
2093 info2
.area
.right
= 20;
2094 info2
.area
.bottom
= 30;
2095 info2
.keyword
= argv
[2];
2096 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2097 info2
.mui_dll
= NULL
;
2098 info2
.ressource_id
= 0;
2099 info2
.display_name
= argv
[2];
2102 info
.info2
= &info2
;
2110 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
2117 if (is_valid_policy_hnd(&handle
))
2118 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2123 /****************************************************************************
2124 ****************************************************************************/
2126 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2127 int argc
, const char **argv
)
2129 struct policy_handle handle
;
2132 const char *printername
;
2133 union spoolss_AddFormInfo info
;
2134 struct spoolss_AddFormInfo1 info1
;
2136 /* Parse the command arguments */
2139 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2143 /* Get a printer handle */
2145 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2147 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2149 SEC_FLAG_MAXIMUM_ALLOWED
,
2151 if (!W_ERROR_IS_OK(werror
))
2154 /* Dummy up some values for the form data */
2156 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2157 info1
.size
.width
= 100;
2158 info1
.size
.height
= 100;
2159 info1
.area
.left
= 0;
2160 info1
.area
.top
= 1000;
2161 info1
.area
.right
= 2000;
2162 info1
.area
.bottom
= 3000;
2163 info1
.form_name
= argv
[2];
2165 info
.info1
= &info1
;
2169 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
2177 if (is_valid_policy_hnd(&handle
))
2178 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2183 /****************************************************************************
2184 ****************************************************************************/
2186 static const char *get_form_flag(int form_flag
)
2188 switch (form_flag
) {
2189 case SPOOLSS_FORM_USER
:
2191 case SPOOLSS_FORM_BUILTIN
:
2192 return "FORM_BUILTIN";
2193 case SPOOLSS_FORM_PRINTER
:
2194 return "FORM_PRINTER";
2200 /****************************************************************************
2201 ****************************************************************************/
2203 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2206 "\tflag: %s (%d)\n" \
2207 "\twidth: %d, length: %d\n" \
2208 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2209 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2210 r
->size
.width
, r
->size
.height
,
2211 r
->area
.left
, r
->area
.right
,
2212 r
->area
.top
, r
->area
.bottom
);
2215 /****************************************************************************
2216 ****************************************************************************/
2218 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2221 "\tflag: %s (%d)\n" \
2222 "\twidth: %d, length: %d\n" \
2223 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2224 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2225 r
->size
.width
, r
->size
.height
,
2226 r
->area
.left
, r
->area
.right
,
2227 r
->area
.top
, r
->area
.bottom
);
2228 printf("\tkeyword: %s\n", r
->keyword
);
2229 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2230 printf("\tmui_dll: %s\n", r
->mui_dll
);
2231 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2232 printf("\tdisplay_name: %s\n", r
->display_name
);
2233 printf("\tlang_id: %d\n", r
->lang_id
);
2237 /****************************************************************************
2238 ****************************************************************************/
2240 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2241 int argc
, const char **argv
)
2243 struct policy_handle handle
;
2246 const char *printername
;
2248 uint32_t offered
= 0;
2249 union spoolss_FormInfo info
;
2253 /* Parse the command arguments */
2255 if (argc
< 3 || argc
> 5) {
2256 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2260 /* Get a printer handle */
2262 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2264 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2266 SEC_FLAG_MAXIMUM_ALLOWED
,
2268 if (!W_ERROR_IS_OK(werror
))
2272 level
= atoi(argv
[3]);
2277 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2286 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2287 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2289 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2300 if (!NT_STATUS_IS_OK(status
)) {
2306 display_form_info1(&info
.info1
);
2309 display_form_info2(&info
.info2
);
2314 if (is_valid_policy_hnd(&handle
))
2315 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2320 /****************************************************************************
2321 ****************************************************************************/
2323 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2324 TALLOC_CTX
*mem_ctx
, int argc
,
2327 struct policy_handle handle
;
2330 const char *printername
;
2332 /* Parse the command arguments */
2335 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2339 /* Get a printer handle */
2341 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2343 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2345 SEC_FLAG_MAXIMUM_ALLOWED
,
2347 if (!W_ERROR_IS_OK(werror
))
2350 /* Delete the form */
2352 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2356 if (!NT_STATUS_IS_OK(status
)) {
2357 return ntstatus_to_werror(status
);
2361 if (is_valid_policy_hnd(&handle
))
2362 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2367 /****************************************************************************
2368 ****************************************************************************/
2370 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2371 TALLOC_CTX
*mem_ctx
, int argc
,
2374 struct policy_handle handle
;
2376 const char *printername
;
2377 uint32_t num_forms
, level
= 1, i
;
2378 union spoolss_FormInfo
*forms
;
2380 /* Parse the command arguments */
2382 if (argc
< 2 || argc
> 4) {
2383 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2387 /* Get a printer handle */
2389 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2391 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2393 SEC_FLAG_MAXIMUM_ALLOWED
,
2395 if (!W_ERROR_IS_OK(werror
))
2399 level
= atoi(argv
[2]);
2402 /* Enumerate forms */
2404 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2411 if (!W_ERROR_IS_OK(werror
))
2414 /* Display output */
2416 for (i
= 0; i
< num_forms
; i
++) {
2419 display_form_info1(&forms
[i
].info1
);
2422 display_form_info2(&forms
[i
].info2
);
2428 if (is_valid_policy_hnd(&handle
))
2429 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2434 /****************************************************************************
2435 ****************************************************************************/
2437 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2438 TALLOC_CTX
*mem_ctx
,
2439 int argc
, const char **argv
)
2443 const char *printername
;
2444 struct policy_handle pol
;
2445 union spoolss_PrinterInfo info
;
2446 enum winreg_Type type
;
2447 union spoolss_PrinterData data
;
2450 /* parse the command arguments */
2452 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2453 " <value> <data>\n",
2458 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2462 if (strequal(argv
[2], "string")) {
2466 if (strequal(argv
[2], "binary")) {
2470 if (strequal(argv
[2], "dword")) {
2474 if (strequal(argv
[2], "multistring")) {
2475 type
= REG_MULTI_SZ
;
2478 if (type
== REG_NONE
) {
2479 printf("Unknown data type: %s\n", argv
[2]);
2480 result
= WERR_INVALID_PARAM
;
2484 /* get a printer handle */
2486 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2488 SEC_FLAG_MAXIMUM_ALLOWED
,
2490 if (!W_ERROR_IS_OK(result
)) {
2494 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2499 if (!W_ERROR_IS_OK(result
)) {
2503 printf("%s\n", current_timestring(mem_ctx
, true));
2504 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2506 /* Set the printer data */
2510 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2511 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2514 data
.value
= strtoul(argv
[4], NULL
, 10);
2517 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2519 case REG_MULTI_SZ
: {
2521 const char **strings
= NULL
;
2523 for (i
=4; i
<argc
; i
++) {
2524 if (strcmp(argv
[i
], "NULL") == 0) {
2527 if (!add_string_to_array(mem_ctx
, argv
[i
],
2530 result
= WERR_NOMEM
;
2534 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2535 if (!data
.string_array
) {
2536 result
= WERR_NOMEM
;
2539 for (i
=0; i
< num_strings
; i
++) {
2540 data
.string_array
[i
] = strings
[i
];
2545 printf("Unknown data type: %s\n", argv
[2]);
2546 result
= WERR_INVALID_PARAM
;
2550 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2551 if (!W_ERROR_IS_OK(result
)) {
2555 status
= rpccli_spoolss_SetPrinterData(cli
, mem_ctx
,
2557 argv
[3], /* value_name */
2562 if (!W_ERROR_IS_OK(result
)) {
2563 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2566 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2568 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2573 if (!W_ERROR_IS_OK(result
)) {
2577 printf("%s\n", current_timestring(mem_ctx
, true));
2578 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2582 if (is_valid_policy_hnd(&pol
)) {
2583 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2589 /****************************************************************************
2590 ****************************************************************************/
2592 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2594 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2595 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2599 /****************************************************************************
2600 ****************************************************************************/
2602 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2604 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2605 r
->position
, r
->job_id
,
2606 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2607 r
->total_pages
, r
->size
);
2610 /****************************************************************************
2611 ****************************************************************************/
2613 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2615 printf("jobid[%d], next_jobid[%d]\n",
2616 r
->job_id
, r
->next_job_id
);
2619 /****************************************************************************
2620 ****************************************************************************/
2622 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2624 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2625 r
->position
, r
->job_id
,
2626 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2627 r
->total_pages
, r
->size
, r
->size_high
);
2630 /****************************************************************************
2631 ****************************************************************************/
2633 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2634 TALLOC_CTX
*mem_ctx
, int argc
,
2638 uint32_t level
= 1, count
, i
;
2639 const char *printername
;
2640 struct policy_handle hnd
;
2641 union spoolss_JobInfo
*info
;
2643 if (argc
< 2 || argc
> 3) {
2644 printf("Usage: %s printername [level]\n", argv
[0]);
2649 level
= atoi(argv
[2]);
2652 /* Open printer handle */
2654 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2656 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2658 SEC_FLAG_MAXIMUM_ALLOWED
,
2660 if (!W_ERROR_IS_OK(result
))
2663 /* Enumerate ports */
2665 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2673 if (!W_ERROR_IS_OK(result
)) {
2677 for (i
= 0; i
< count
; i
++) {
2680 display_job_info1(&info
[i
].info1
);
2683 display_job_info2(&info
[i
].info2
);
2686 d_printf("unknown info level %d\n", level
);
2692 if (is_valid_policy_hnd(&hnd
)) {
2693 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2699 /****************************************************************************
2700 ****************************************************************************/
2702 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2703 TALLOC_CTX
*mem_ctx
, int argc
,
2707 const char *printername
;
2708 struct policy_handle hnd
;
2711 union spoolss_JobInfo info
;
2713 if (argc
< 3 || argc
> 4) {
2714 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2718 job_id
= atoi(argv
[2]);
2721 level
= atoi(argv
[3]);
2724 /* Open printer handle */
2726 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2728 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2730 SEC_FLAG_MAXIMUM_ALLOWED
,
2732 if (!W_ERROR_IS_OK(result
)) {
2736 /* Enumerate ports */
2738 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2745 if (!W_ERROR_IS_OK(result
)) {
2751 display_job_info1(&info
.info1
);
2754 display_job_info2(&info
.info2
);
2757 display_job_info3(&info
.info3
);
2760 display_job_info4(&info
.info4
);
2763 d_printf("unknown info level %d\n", level
);
2768 if (is_valid_policy_hnd(&hnd
)) {
2769 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2775 /****************************************************************************
2776 ****************************************************************************/
2778 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2779 TALLOC_CTX
*mem_ctx
, int argc
,
2784 const char *printername
;
2785 struct policy_handle hnd
;
2787 enum spoolss_JobControl command
;
2790 printf("Usage: %s printername job_id command\n", argv
[0]);
2794 job_id
= atoi(argv
[2]);
2795 command
= atoi(argv
[3]);
2797 /* Open printer handle */
2799 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2801 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2803 SEC_FLAG_MAXIMUM_ALLOWED
,
2805 if (!W_ERROR_IS_OK(result
)) {
2811 status
= rpccli_spoolss_SetJob(cli
, mem_ctx
,
2818 if (!W_ERROR_IS_OK(result
)) {
2823 if (is_valid_policy_hnd(&hnd
)) {
2824 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2830 /****************************************************************************
2831 ****************************************************************************/
2833 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2834 TALLOC_CTX
*mem_ctx
, int argc
,
2840 const char *printername
;
2841 struct policy_handle hnd
;
2842 uint32_t value_offered
= 0;
2843 const char *value_name
= NULL
;
2844 uint32_t value_needed
;
2845 enum winreg_Type type
;
2846 uint8_t *data
= NULL
;
2847 uint32_t data_offered
= 0;
2848 uint32_t data_needed
;
2851 printf("Usage: %s printername\n", argv
[0]);
2855 /* Open printer handle */
2857 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2859 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2861 SEC_FLAG_MAXIMUM_ALLOWED
,
2863 if (!W_ERROR_IS_OK(result
)) {
2867 /* Enumerate data */
2869 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2881 data_offered
= data_needed
;
2882 value_offered
= value_needed
;
2883 data
= talloc_zero_array(mem_ctx
, uint8_t, data_needed
);
2884 value_name
= talloc_zero_array(mem_ctx
, char, value_needed
);
2886 while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2888 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2899 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2900 struct regval_blob v
;
2901 fstrcpy(v
.valuename
, value_name
);
2903 v
.size
= data_offered
;
2905 display_reg_value(v
);
2909 if (W_ERROR_V(result
) == ERRnomoreitems
) {
2910 result
= W_ERROR(ERRsuccess
);
2914 if (is_valid_policy_hnd(&hnd
)) {
2915 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2921 /****************************************************************************
2922 ****************************************************************************/
2924 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2925 TALLOC_CTX
*mem_ctx
, int argc
,
2930 const char *printername
;
2931 struct policy_handle hnd
;
2933 struct spoolss_PrinterEnumValues
*info
;
2936 printf("Usage: %s printername <keyname>\n", argv
[0]);
2940 /* Open printer handle */
2942 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2944 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2946 SEC_FLAG_MAXIMUM_ALLOWED
,
2948 if (!W_ERROR_IS_OK(result
)) {
2952 /* Enumerate subkeys */
2954 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
2960 if (!W_ERROR_IS_OK(result
)) {
2964 for (i
=0; i
< count
; i
++) {
2965 display_printer_data(info
[i
].value_name
,
2968 info
[i
].data
->length
);
2972 if (is_valid_policy_hnd(&hnd
)) {
2973 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2979 /****************************************************************************
2980 ****************************************************************************/
2982 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
2983 TALLOC_CTX
*mem_ctx
, int argc
,
2987 const char *printername
;
2988 const char *keyname
= NULL
;
2989 struct policy_handle hnd
;
2990 const char **key_buffer
= NULL
;
2992 uint32_t offered
= 0;
2994 if (argc
< 2 || argc
> 4) {
2995 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3006 offered
= atoi(argv
[3]);
3009 /* Open printer handle */
3011 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3013 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3015 SEC_FLAG_MAXIMUM_ALLOWED
,
3017 if (!W_ERROR_IS_OK(result
)) {
3021 /* Enumerate subkeys */
3023 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3029 if (!W_ERROR_IS_OK(result
)) {
3033 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3034 printf("%s\n", key_buffer
[i
]);
3039 if (is_valid_policy_hnd(&hnd
)) {
3040 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3046 /****************************************************************************
3047 ****************************************************************************/
3049 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3050 TALLOC_CTX
*mem_ctx
, int argc
,
3053 const char *printername
;
3054 const char *clientname
;
3055 struct policy_handle hnd
;
3058 struct spoolss_NotifyOption option
;
3061 printf("Usage: %s printername\n", argv
[0]);
3068 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3070 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3072 SEC_FLAG_MAXIMUM_ALLOWED
,
3074 if (!W_ERROR_IS_OK(result
)) {
3075 printf("Error opening %s\n", argv
[1]);
3079 /* Create spool options */
3084 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3085 if (option
.types
== NULL
) {
3086 result
= WERR_NOMEM
;
3090 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3091 option
.types
[0].count
= 1;
3092 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3093 if (option
.types
[0].fields
== NULL
) {
3094 result
= WERR_NOMEM
;
3097 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3099 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3100 option
.types
[1].count
= 1;
3101 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3102 if (option
.types
[1].fields
== NULL
) {
3103 result
= WERR_NOMEM
;
3106 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3108 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
3110 result
= WERR_NOMEM
;
3116 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
3124 if (!W_ERROR_IS_OK(result
)) {
3125 printf("Error rffpcnex %s\n", argv
[1]);
3130 if (is_valid_policy_hnd(&hnd
))
3131 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3136 /****************************************************************************
3137 ****************************************************************************/
3139 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3140 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3142 union spoolss_PrinterInfo info1
, info2
;
3144 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3146 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3147 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3152 if ( !W_ERROR_IS_OK(werror
) ) {
3153 printf("failed (%s)\n", win_errstr(werror
));
3154 talloc_destroy(mem_ctx
);
3159 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3160 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3165 if ( !W_ERROR_IS_OK(werror
) ) {
3166 printf("failed (%s)\n", win_errstr(werror
));
3167 talloc_destroy(mem_ctx
);
3172 talloc_destroy(mem_ctx
);
3177 /****************************************************************************
3178 ****************************************************************************/
3180 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3181 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3183 union spoolss_PrinterInfo info1
, info2
;
3185 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3186 SEC_DESC
*sd1
, *sd2
;
3190 printf("Retrieving printer security for %s...", cli1
->desthost
);
3191 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3196 if ( !W_ERROR_IS_OK(werror
) ) {
3197 printf("failed (%s)\n", win_errstr(werror
));
3203 printf("Retrieving printer security for %s...", cli2
->desthost
);
3204 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3209 if ( !W_ERROR_IS_OK(werror
) ) {
3210 printf("failed (%s)\n", win_errstr(werror
));
3219 sd1
= info1
.info3
.secdesc
;
3220 sd2
= info2
.info3
.secdesc
;
3222 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3223 printf("NULL secdesc!\n");
3228 if (!security_descriptor_equal( sd1
, sd2
) ) {
3229 printf("Security Descriptors *not* equal!\n");
3234 printf("Security descriptors match\n");
3237 talloc_destroy(mem_ctx
);
3242 /****************************************************************************
3243 ****************************************************************************/
3245 extern struct user_auth_info
*rpcclient_auth_info
;
3247 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3248 TALLOC_CTX
*mem_ctx
, int argc
,
3251 const char *printername
;
3252 char *printername_path
= NULL
;
3253 struct cli_state
*cli_server2
= NULL
;
3254 struct rpc_pipe_client
*cli2
= NULL
;
3255 struct policy_handle hPrinter1
, hPrinter2
;
3260 printf("Usage: %s <printer> <server>\n", argv
[0]);
3264 printername
= argv
[1];
3266 /* first get the connection to the remote server */
3268 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
3271 get_cmdline_auth_info_username(rpcclient_auth_info
),
3273 get_cmdline_auth_info_password(rpcclient_auth_info
),
3274 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3275 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
3277 if ( !NT_STATUS_IS_OK(nt_status
) )
3278 return WERR_GENERAL_FAILURE
;
3280 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
.syntax_id
,
3282 if (!NT_STATUS_IS_OK(nt_status
)) {
3283 printf("failed to open spoolss pipe on server %s (%s)\n",
3284 argv
[2], nt_errstr(nt_status
));
3285 return WERR_GENERAL_FAILURE
;
3288 /* now open up both printers */
3290 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3292 printf("Opening %s...", printername_path
);
3294 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3298 if ( !W_ERROR_IS_OK(werror
) ) {
3299 printf("failed (%s)\n", win_errstr(werror
));
3304 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3306 printf("Opening %s...", printername_path
);
3307 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3311 if ( !W_ERROR_IS_OK(werror
) ) {
3312 printf("failed (%s)\n", win_errstr(werror
));
3317 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3318 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3320 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3327 printf("Closing printers...");
3328 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3329 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3332 /* close the second remote connection */
3334 cli_shutdown( cli_server2
);
3338 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3340 printf("print_processor_name: %s\n", r
->print_processor_name
);
3343 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3344 TALLOC_CTX
*mem_ctx
, int argc
,
3348 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3349 uint32_t num_procs
, level
= 1, i
;
3350 union spoolss_PrintProcessorInfo
*procs
;
3352 /* Parse the command arguments */
3354 if (argc
< 1 || argc
> 4) {
3355 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3360 environment
= argv
[1];
3364 level
= atoi(argv
[2]);
3367 /* Enumerate Print Processors */
3369 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3370 cli
->srv_name_slash
,
3376 if (!W_ERROR_IS_OK(werror
))
3379 /* Display output */
3381 for (i
= 0; i
< num_procs
; i
++) {
3384 display_proc_info1(&procs
[i
].info1
);
3393 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3395 printf("name_array: %s\n", r
->name_array
);
3398 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3399 TALLOC_CTX
*mem_ctx
, int argc
,
3403 const char *print_processor_name
= "winprint";
3404 uint32_t num_procs
, level
= 1, i
;
3405 union spoolss_PrintProcDataTypesInfo
*procs
;
3407 /* Parse the command arguments */
3409 if (argc
< 1 || argc
> 4) {
3410 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3415 print_processor_name
= argv
[1];
3419 level
= atoi(argv
[2]);
3422 /* Enumerate Print Processor Data Types */
3424 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3425 cli
->srv_name_slash
,
3426 print_processor_name
,
3431 if (!W_ERROR_IS_OK(werror
))
3434 /* Display output */
3436 for (i
= 0; i
< num_procs
; i
++) {
3439 display_proc_data_types_info1(&procs
[i
].info1
);
3448 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3450 printf("monitor_name: %s\n", r
->monitor_name
);
3453 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3455 printf("monitor_name: %s\n", r
->monitor_name
);
3456 printf("environment: %s\n", r
->environment
);
3457 printf("dll_name: %s\n", r
->dll_name
);
3460 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3461 TALLOC_CTX
*mem_ctx
, int argc
,
3465 uint32_t count
, level
= 1, i
;
3466 union spoolss_MonitorInfo
*info
;
3468 /* Parse the command arguments */
3471 printf("Usage: %s [level]\n", argv
[0]);
3476 level
= atoi(argv
[1]);
3479 /* Enumerate Print Monitors */
3481 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3482 cli
->srv_name_slash
,
3487 if (!W_ERROR_IS_OK(werror
)) {
3491 /* Display output */
3493 for (i
= 0; i
< count
; i
++) {
3496 display_monitor1(&info
[i
].info1
);
3499 display_monitor2(&info
[i
].info2
);
3508 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3509 TALLOC_CTX
*mem_ctx
, int argc
,
3514 struct policy_handle handle
, gdi_handle
;
3515 const char *printername
;
3516 struct spoolss_DevmodeContainer devmode_ctr
;
3518 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3520 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3522 SEC_FLAG_MAXIMUM_ALLOWED
,
3524 if (!W_ERROR_IS_OK(result
)) {
3528 ZERO_STRUCT(devmode_ctr
);
3530 status
= rpccli_spoolss_CreatePrinterIC(cli
, mem_ctx
,
3535 if (!W_ERROR_IS_OK(result
)) {
3540 if (is_valid_policy_hnd(&gdi_handle
)) {
3541 rpccli_spoolss_DeletePrinterIC(cli
, mem_ctx
, &gdi_handle
, NULL
);
3543 if (is_valid_policy_hnd(&handle
)) {
3544 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
3550 /* List of commands exported by this module */
3551 struct cmd_set spoolss_commands
[] = {
3555 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a print driver", "" },
3556 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a printer", "" },
3557 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver", "" },
3558 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver with files", "" },
3559 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data", "" },
3560 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data for a key", "" },
3561 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer keys", "" },
3562 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate print jobs", "" },
3563 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print job", "" },
3564 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set print job", "" },
3565 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer ports", "" },
3566 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate installed printer drivers", "" },
3567 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printers", "" },
3568 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver data", "" },
3569 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer driver data with keyname", ""},
3570 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver information", "" },
3571 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver upload directory", "" },
3572 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer info", "" },
3573 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3574 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer driver", "" },
3575 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print processor directory", "" },
3576 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add form", "" },
3577 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set form", "" },
3578 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get form", "" },
3579 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete form", "" },
3580 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate forms", "" },
3581 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer comment", "" },
3582 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printername", "" },
3583 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set REG_SZ printer data", "" },
3584 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Rffpcnex test", "" },
3585 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
.syntax_id
, NULL
, "Printer comparison test", "" },
3586 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processors", "" },
3587 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processor Data Types", "" },
3588 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Monitors", "" },
3589 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
.syntax_id
, NULL
, "Create Printer IC", "" },