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"
31 #include "registry/reg_objects.h"
33 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
35 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
36 _cli->srv_name_slash, _arg); \
37 W_ERROR_HAVE_NO_MEMORY(_printername); \
40 /* The version int is used by getdrivers. Note that
41 all architecture strings that support mutliple
42 versions must be grouped together since enumdrivers
43 uses this property to prevent issuing multiple
44 enumdriver calls for the same arch */
47 static const struct print_architecture_table_node archi_table
[]= {
49 {"Windows 4.0", "WIN40", 0 },
50 {"Windows NT x86", "W32X86", 2 },
51 {"Windows NT x86", "W32X86", 3 },
52 {"Windows NT R4000", "W32MIPS", 2 },
53 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
54 {"Windows NT PowerPC", "W32PPC", 2 },
55 {"Windows IA64", "IA64", 3 },
56 {"Windows x64", "x64", 3 },
63 * rpcclient module for SPOOLSS rpc pipe.
65 * This generally just parses and checks command lines, and then calls
66 * a cli_spoolss function.
69 /****************************************************************************
70 function to do the mapping between the long architecture name and
72 ****************************************************************************/
74 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
78 DEBUG(107,("Getting architecture dependant directory\n"));
81 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
82 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
84 if (archi_table
[i
].long_archi
==NULL
) {
85 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
89 /* this might be client code - but shouldn't this be an fstrcpy etc? */
92 DEBUGADD(108,("index: [%d]\n", i
));
93 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
94 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
96 return archi_table
[i
].short_archi
;
99 /****************************************************************************
100 ****************************************************************************/
102 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
104 int argc
, const char **argv
)
107 struct policy_handle hnd
;
110 printf("Usage: %s <printername>\n", argv
[0]);
115 return WERR_GENERAL_FAILURE
;
117 /* Open the printer handle */
119 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
123 if (W_ERROR_IS_OK(werror
)) {
124 printf("Printer %s opened successfully\n", argv
[1]);
125 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
127 if (!W_ERROR_IS_OK(werror
)) {
128 printf("Error closing printer handle! (%s)\n",
129 get_dos_error_msg(werror
));
137 /****************************************************************************
138 ****************************************************************************/
140 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
145 printf("\tprintername:[%s]\n", r
->printername
);
146 printf("\tservername:[%s]\n", r
->servername
);
147 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
148 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
149 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
150 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
151 r
->time
.day
, r
->time
.day_of_week
);
152 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
153 r
->time
.second
, r
->time
.millisecond
);
155 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
156 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
158 printf("\tversion:[0x%x]\n", r
->version
);
159 printf("\tfree_build:[0x%x]\n", r
->free_build
);
160 printf("\tspooling:[0x%x]\n", r
->spooling
);
161 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
162 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
163 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
164 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
165 printf("\tjob_error:[0x%x]\n", r
->job_error
);
166 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
167 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
168 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
169 printf("\tchange_id:[0x%x]\n", r
->change_id
);
170 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
171 printf("\tstatus:[0x%x]\n", r
->status
);
172 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
173 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
174 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
175 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
176 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
177 printf("\treserved2:[0x%x]\n", r
->reserved2
);
178 printf("\treserved3:[0x%x]\n", r
->reserved3
);
183 /****************************************************************************
184 ****************************************************************************/
186 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
188 printf("\tflags:[0x%x]\n", r
->flags
);
189 printf("\tname:[%s]\n", r
->name
);
190 printf("\tdescription:[%s]\n", r
->description
);
191 printf("\tcomment:[%s]\n", r
->comment
);
196 /****************************************************************************
197 ****************************************************************************/
199 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
201 printf("\tservername:[%s]\n", r
->servername
);
202 printf("\tprintername:[%s]\n", r
->printername
);
203 printf("\tsharename:[%s]\n", r
->sharename
);
204 printf("\tportname:[%s]\n", r
->portname
);
205 printf("\tdrivername:[%s]\n", r
->drivername
);
206 printf("\tcomment:[%s]\n", r
->comment
);
207 printf("\tlocation:[%s]\n", r
->location
);
208 printf("\tsepfile:[%s]\n", r
->sepfile
);
209 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
210 printf("\tdatatype:[%s]\n", r
->datatype
);
211 printf("\tparameters:[%s]\n", r
->parameters
);
212 printf("\tattributes:[0x%x]\n", r
->attributes
);
213 printf("\tpriority:[0x%x]\n", r
->priority
);
214 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
215 printf("\tstarttime:[0x%x]\n", r
->starttime
);
216 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
217 printf("\tstatus:[0x%x]\n", r
->status
);
218 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
219 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
222 display_sec_desc(r
->secdesc
);
227 /****************************************************************************
228 ****************************************************************************/
230 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
232 display_sec_desc(r
->secdesc
);
237 /****************************************************************************
238 ****************************************************************************/
240 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
242 printf("\tservername:[%s]\n", r
->servername
);
243 printf("\tprintername:[%s]\n", r
->printername
);
244 printf("\tattributes:[0x%x]\n", r
->attributes
);
248 /****************************************************************************
249 ****************************************************************************/
251 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
253 printf("\tprintername:[%s]\n", r
->printername
);
254 printf("\tportname:[%s]\n", r
->portname
);
255 printf("\tattributes:[0x%x]\n", r
->attributes
);
256 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
257 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
261 /****************************************************************************
262 ****************************************************************************/
264 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
266 printf("\tstatus:[0x%x]\n", r
->status
);
270 /****************************************************************************
271 ****************************************************************************/
273 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
275 printf("\tguid:[%s]\n", r
->guid
);
276 printf("\taction:[0x%x]\n", r
->action
);
280 /****************************************************************************
281 ****************************************************************************/
283 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
285 int argc
, const char **argv
)
289 union spoolss_PrinterInfo
*info
;
292 uint32_t flags
= PRINTER_ENUM_LOCAL
;
295 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
300 level
= atoi(argv
[1]);
306 name
= cli
->srv_name_slash
;
310 flags
= atoi(argv
[3]);
313 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
320 if (W_ERROR_IS_OK(result
)) {
323 printf ("No printers returned.\n");
327 for (i
= 0; i
< count
; i
++) {
330 display_print_info0(&info
[i
].info0
);
333 display_print_info1(&info
[i
].info1
);
336 display_print_info2(&info
[i
].info2
);
339 display_print_info3(&info
[i
].info3
);
342 display_print_info4(&info
[i
].info4
);
345 display_print_info5(&info
[i
].info5
);
348 display_print_info6(&info
[i
].info6
);
351 printf("unknown info level %d\n", level
);
361 /****************************************************************************
362 ****************************************************************************/
364 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
366 printf("\tPort Name:\t[%s]\n", r
->port_name
);
369 /****************************************************************************
370 ****************************************************************************/
372 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
374 printf("\tPort Name:\t[%s]\n", r
->port_name
);
375 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
376 printf("\tDescription:\t[%s]\n", r
->description
);
377 printf("\tPort Type:\t" );
379 int comma
= 0; /* hack */
381 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
385 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
386 printf( "%sWrite", comma
? ", " : "" );
389 /* These two have slightly different interpretations
390 on 95/98/ME but I'm disregarding that for now */
391 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
392 printf( "%sRedirected", comma
? ", " : "" );
395 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
396 printf( "%sNet-Attached", comma
? ", " : "" );
400 printf( "[Unset]\n" );
402 printf("\tReserved:\t[%d]\n", r
->reserved
);
406 /****************************************************************************
407 ****************************************************************************/
409 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
410 TALLOC_CTX
*mem_ctx
, int argc
,
416 union spoolss_PortInfo
*info
;
419 printf("Usage: %s [level]\n", argv
[0]);
424 level
= atoi(argv
[1]);
427 /* Enumerate ports */
429 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
435 if (W_ERROR_IS_OK(result
)) {
438 for (i
= 0; i
< count
; i
++) {
441 display_port_info_1(&info
[i
].info1
);
444 display_port_info_2(&info
[i
].info2
);
447 printf("unknown info level %d\n", level
);
456 /****************************************************************************
457 ****************************************************************************/
459 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
461 int argc
, const char **argv
)
463 struct policy_handle pol
;
466 uint32_t info_level
= 2;
467 union spoolss_PrinterInfo info
;
468 struct spoolss_SetPrinterInfoCtr info_ctr
;
469 struct spoolss_SetPrinterInfo2 info2
;
470 const char *printername
, *comment
= NULL
;
471 struct spoolss_DevmodeContainer devmode_ctr
;
472 struct sec_desc_buf secdesc_ctr
;
474 if (argc
== 1 || argc
> 3) {
475 printf("Usage: %s printername comment\n", argv
[0]);
480 /* Open a printer handle */
485 ZERO_STRUCT(devmode_ctr
);
486 ZERO_STRUCT(secdesc_ctr
);
488 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
490 /* get a printer handle */
491 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
495 if (!W_ERROR_IS_OK(result
))
498 /* Get printer info */
499 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
504 if (!W_ERROR_IS_OK(result
))
508 /* Modify the comment. */
509 info2
.servername
= info
.info2
.servername
;
510 info2
.printername
= info
.info2
.printername
;
511 info2
.sharename
= info
.info2
.sharename
;
512 info2
.portname
= info
.info2
.portname
;
513 info2
.drivername
= info
.info2
.drivername
;
514 info2
.comment
= comment
;
515 info2
.location
= info
.info2
.location
;
516 info2
.devmode_ptr
= 0;
517 info2
.sepfile
= info
.info2
.sepfile
;
518 info2
.printprocessor
= info
.info2
.printprocessor
;
519 info2
.datatype
= info
.info2
.datatype
;
520 info2
.parameters
= info
.info2
.parameters
;
521 info2
.secdesc_ptr
= 0;
522 info2
.attributes
= info
.info2
.attributes
;
523 info2
.priority
= info
.info2
.priority
;
524 info2
.defaultpriority
= info
.info2
.defaultpriority
;
525 info2
.starttime
= info
.info2
.starttime
;
526 info2
.untiltime
= info
.info2
.untiltime
;
527 info2
.status
= info
.info2
.status
;
528 info2
.cjobs
= info
.info2
.cjobs
;
529 info2
.averageppm
= info
.info2
.averageppm
;
532 info_ctr
.info
.info2
= &info2
;
534 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
541 if (W_ERROR_IS_OK(result
))
542 printf("Success in setting comment.\n");
545 if (is_valid_policy_hnd(&pol
))
546 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
551 /****************************************************************************
552 ****************************************************************************/
554 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
556 int argc
, const char **argv
)
558 struct policy_handle pol
;
561 uint32_t info_level
= 2;
562 union spoolss_PrinterInfo info
;
563 const char *printername
,
564 *new_printername
= NULL
;
565 struct spoolss_SetPrinterInfoCtr info_ctr
;
566 struct spoolss_SetPrinterInfo2 info2
;
567 struct spoolss_DevmodeContainer devmode_ctr
;
568 struct sec_desc_buf secdesc_ctr
;
570 ZERO_STRUCT(devmode_ctr
);
571 ZERO_STRUCT(secdesc_ctr
);
573 if (argc
== 1 || argc
> 3) {
574 printf("Usage: %s printername new_printername\n", argv
[0]);
579 /* Open a printer handle */
581 new_printername
= argv
[2];
584 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
586 /* get a printer handle */
587 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
591 if (!W_ERROR_IS_OK(result
))
594 /* Get printer info */
595 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
600 if (!W_ERROR_IS_OK(result
))
603 /* Modify the printername. */
604 info2
.servername
= info
.info2
.servername
;
605 info2
.printername
= new_printername
;
606 info2
.sharename
= info
.info2
.sharename
;
607 info2
.portname
= info
.info2
.portname
;
608 info2
.drivername
= info
.info2
.drivername
;
609 info2
.comment
= info
.info2
.comment
;
610 info2
.location
= info
.info2
.location
;
611 info2
.devmode_ptr
= 0;
612 info2
.sepfile
= info
.info2
.sepfile
;
613 info2
.printprocessor
= info
.info2
.printprocessor
;
614 info2
.datatype
= info
.info2
.datatype
;
615 info2
.parameters
= info
.info2
.parameters
;
616 info2
.secdesc_ptr
= 0;
617 info2
.attributes
= info
.info2
.attributes
;
618 info2
.priority
= info
.info2
.priority
;
619 info2
.defaultpriority
= info
.info2
.defaultpriority
;
620 info2
.starttime
= info
.info2
.starttime
;
621 info2
.untiltime
= info
.info2
.untiltime
;
622 info2
.status
= info
.info2
.status
;
623 info2
.cjobs
= info
.info2
.cjobs
;
624 info2
.averageppm
= info
.info2
.averageppm
;
627 info_ctr
.info
.info2
= &info2
;
629 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
636 if (W_ERROR_IS_OK(result
))
637 printf("Success in setting printername.\n");
640 if (is_valid_policy_hnd(&pol
))
641 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
646 /****************************************************************************
647 ****************************************************************************/
649 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
651 int argc
, const char **argv
)
653 struct policy_handle pol
;
656 const char *printername
;
657 union spoolss_PrinterInfo info
;
659 if (argc
== 1 || argc
> 3) {
660 printf("Usage: %s <printername> [level]\n", argv
[0]);
664 /* Open a printer handle */
666 level
= atoi(argv
[2]);
669 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
671 /* get a printer handle */
673 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
675 SEC_FLAG_MAXIMUM_ALLOWED
,
677 if (!W_ERROR_IS_OK(result
)) {
681 /* Get printer info */
683 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
688 if (!W_ERROR_IS_OK(result
)) {
692 /* Display printer info */
695 display_print_info0(&info
.info0
);
698 display_print_info1(&info
.info1
);
701 display_print_info2(&info
.info2
);
704 display_print_info3(&info
.info3
);
707 display_print_info4(&info
.info4
);
710 display_print_info5(&info
.info5
);
713 display_print_info6(&info
.info6
);
716 display_print_info7(&info
.info7
);
719 printf("unknown info level %d\n", level
);
723 if (is_valid_policy_hnd(&pol
)) {
724 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
730 /****************************************************************************
731 ****************************************************************************/
733 static void display_reg_value(struct regval_blob
*value
)
735 const char *text
= NULL
;
738 switch(regval_type(value
)) {
740 printf("%s: REG_DWORD: 0x%08x\n", regval_name(value
),
741 *((uint32_t *) regval_data_p(value
)));
744 blob
= data_blob_const(regval_data_p(value
), regval_size(value
));
745 pull_reg_sz(talloc_tos(), &blob
, &text
);
746 printf("%s: REG_SZ: %s\n", regval_name(value
), text
? text
: "");
749 char *hex
= hex_encode_talloc(NULL
, regval_data_p(value
), regval_size(value
));
751 printf("%s: REG_BINARY:", regval_name(value
));
753 for (i
=0; i
<len
; i
++) {
754 if (hex
[i
] == '\0') {
769 blob
= data_blob_const(regval_data_p(value
), regval_size(value
));
771 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
772 d_printf("pull_reg_multi_sz failed\n");
776 printf("%s: REG_MULTI_SZ: \n", regval_name(value
));
777 for (i
=0; values
[i
] != NULL
; i
++) {
778 d_printf("%s\n", values
[i
]);
784 printf("%s: unknown type %d\n", regval_name(value
), regval_type(value
));
789 /****************************************************************************
790 ****************************************************************************/
792 static void display_printer_data(const char *v
,
793 enum winreg_Type type
,
798 union spoolss_PrinterData r
;
799 DATA_BLOB blob
= data_blob_const(data
, length
);
802 result
= pull_spoolss_PrinterData(talloc_tos(), &blob
, &r
, type
);
803 if (!W_ERROR_IS_OK(result
)) {
809 printf("%s: REG_DWORD: 0x%08x\n", v
, r
.value
);
812 printf("%s: REG_SZ: %s\n", v
, r
.string
);
815 char *hex
= hex_encode_talloc(NULL
,
816 r
.binary
.data
, r
.binary
.length
);
818 printf("%s: REG_BINARY:", v
);
820 for (i
=0; i
<len
; i
++) {
821 if (hex
[i
] == '\0') {
834 printf("%s: REG_MULTI_SZ: ", v
);
835 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
836 printf("%s ", r
.string_array
[i
]);
841 printf("%s: unknown type 0x%02x:\n", v
, type
);
846 /****************************************************************************
847 ****************************************************************************/
849 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
851 int argc
, const char **argv
)
853 struct policy_handle pol
;
856 const char *valuename
;
857 enum winreg_Type type
;
862 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
863 printf("<printername> of . queries print server\n");
868 /* Open a printer handle */
870 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
871 fstrcpy(printername
, cli
->srv_name_slash
);
873 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
874 cli
->srv_name_slash
, argv
[1]);
876 /* get a printer handle */
878 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
880 SEC_FLAG_MAXIMUM_ALLOWED
,
882 if (!W_ERROR_IS_OK(result
))
885 /* Get printer info */
887 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
894 if (!W_ERROR_IS_OK(result
))
897 /* Display printer data */
899 display_printer_data(valuename
, type
, data
, needed
);
902 if (is_valid_policy_hnd(&pol
))
903 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
908 /****************************************************************************
909 ****************************************************************************/
911 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
913 int argc
, const char **argv
)
915 struct policy_handle pol
;
919 const char *valuename
, *keyname
;
921 enum winreg_Type type
;
922 uint8_t *data
= NULL
;
923 uint32_t offered
= 0;
927 printf("Usage: %s <printername> <keyname> <valuename>\n",
929 printf("<printername> of . queries print server\n");
935 /* Open a printer handle */
937 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
938 fstrcpy(printername
, cli
->srv_name_slash
);
940 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
941 cli
->srv_name_slash
, argv
[1]);
943 /* get a printer handle */
945 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
947 SEC_FLAG_MAXIMUM_ALLOWED
,
949 if (!W_ERROR_IS_OK(result
))
952 /* Get printer info */
954 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
959 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
968 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
970 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
974 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
985 if (!NT_STATUS_IS_OK(status
)) {
989 if (!W_ERROR_IS_OK(result
))
992 /* Display printer data */
994 display_printer_data(valuename
, type
, data
, needed
);
998 if (is_valid_policy_hnd(&pol
))
999 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1004 /****************************************************************************
1005 ****************************************************************************/
1007 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1013 printf("Printer Driver Info 1:\n");
1014 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1018 /****************************************************************************
1019 ****************************************************************************/
1021 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1027 printf("Printer Driver Info 2:\n");
1028 printf("\tVersion: [%x]\n", r
->version
);
1029 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1030 printf("\tArchitecture: [%s]\n", r
->architecture
);
1031 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1032 printf("\tDatafile: [%s]\n", r
->data_file
);
1033 printf("\tConfigfile: [%s]\n", r
->config_file
);
1037 /****************************************************************************
1038 ****************************************************************************/
1040 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1048 printf("Printer Driver Info 3:\n");
1049 printf("\tVersion: [%x]\n", r
->version
);
1050 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1051 printf("\tArchitecture: [%s]\n", r
->architecture
);
1052 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1053 printf("\tDatafile: [%s]\n", r
->data_file
);
1054 printf("\tConfigfile: [%s]\n", r
->config_file
);
1055 printf("\tHelpfile: [%s]\n", r
->help_file
);
1057 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1058 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1061 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1062 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1066 /****************************************************************************
1067 ****************************************************************************/
1069 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1077 printf("Printer Driver Info 4:\n");
1078 printf("\tVersion: [%x]\n", r
->version
);
1079 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1080 printf("\tArchitecture: [%s]\n", r
->architecture
);
1081 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1082 printf("\tDatafile: [%s]\n", r
->data_file
);
1083 printf("\tConfigfile: [%s]\n", r
->config_file
);
1084 printf("\tHelpfile: [%s]\n", r
->help_file
);
1086 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1087 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1090 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1091 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1093 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1094 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1099 /****************************************************************************
1100 ****************************************************************************/
1102 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1108 printf("Printer Driver Info 5:\n");
1109 printf("\tVersion: [%x]\n", r
->version
);
1110 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1111 printf("\tArchitecture: [%s]\n", r
->architecture
);
1112 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1113 printf("\tDatafile: [%s]\n", r
->data_file
);
1114 printf("\tConfigfile: [%s]\n", r
->config_file
);
1115 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1116 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1117 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1121 /****************************************************************************
1122 ****************************************************************************/
1124 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1132 printf("Printer Driver Info 6:\n");
1133 printf("\tVersion: [%x]\n", r
->version
);
1134 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1135 printf("\tArchitecture: [%s]\n", r
->architecture
);
1136 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1137 printf("\tDatafile: [%s]\n", r
->data_file
);
1138 printf("\tConfigfile: [%s]\n", r
->config_file
);
1139 printf("\tHelpfile: [%s]\n", r
->help_file
);
1141 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1142 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1145 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1146 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1148 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1149 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1152 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1153 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1154 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1155 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1156 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1157 printf("\tProvider: [%s]\n", r
->provider
);
1162 /****************************************************************************
1163 ****************************************************************************/
1165 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1173 printf("Printer Driver Info 8:\n");
1174 printf("\tVersion: [%x]\n", r
->version
);
1175 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1176 printf("\tArchitecture: [%s]\n", r
->architecture
);
1177 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1178 printf("\tDatafile: [%s]\n", r
->data_file
);
1179 printf("\tConfigfile: [%s]\n", r
->config_file
);
1180 printf("\tHelpfile: [%s]\n", r
->help_file
);
1181 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1182 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1184 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1185 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1188 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1189 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1192 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1193 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1194 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1195 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1196 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1197 printf("\tProvider: [%s]\n", r
->provider
);
1198 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1199 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1200 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1201 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1203 printf("\tInf Path: [%s]\n", r
->inf_path
);
1204 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1205 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1206 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1208 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1209 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1210 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1215 /****************************************************************************
1216 ****************************************************************************/
1218 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1219 TALLOC_CTX
*mem_ctx
,
1220 int argc
, const char **argv
)
1222 struct policy_handle pol
;
1225 const char *printername
;
1227 bool success
= false;
1228 union spoolss_DriverInfo info
;
1229 uint32_t server_major_version
;
1230 uint32_t server_minor_version
;
1232 if ((argc
== 1) || (argc
> 3)) {
1233 printf("Usage: %s <printername> [level]\n", argv
[0]);
1237 /* get the arguments need to open the printer handle */
1239 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1242 level
= atoi(argv
[2]);
1245 /* Open a printer handle */
1247 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1251 if (!W_ERROR_IS_OK(werror
)) {
1252 printf("Error opening printer handle for %s!\n", printername
);
1256 /* loop through and print driver info level for each architecture */
1258 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1260 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1262 archi_table
[i
].long_archi
,
1265 archi_table
[i
].version
,
1268 &server_major_version
,
1269 &server_minor_version
);
1270 if (!W_ERROR_IS_OK(werror
)) {
1274 /* need at least one success */
1278 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1282 display_print_driver1(&info
.info1
);
1285 display_print_driver2(&info
.info2
);
1288 display_print_driver3(&info
.info3
);
1291 display_print_driver4(&info
.info4
);
1294 display_print_driver5(&info
.info5
);
1297 display_print_driver6(&info
.info6
);
1300 display_print_driver8(&info
.info8
);
1303 printf("unknown info level %d\n", level
);
1310 if (is_valid_policy_hnd(&pol
)) {
1311 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1321 /****************************************************************************
1322 ****************************************************************************/
1324 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1325 TALLOC_CTX
*mem_ctx
,
1326 const char *architecture
,
1331 union spoolss_DriverInfo
*info
= NULL
;
1334 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1335 cli
->srv_name_slash
,
1342 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1343 printf("Server does not support environment [%s]\n",
1352 if (!W_ERROR_IS_OK(werror
)) {
1353 printf("Error getting driver for environment [%s] - %s\n",
1354 architecture
, win_errstr(werror
));
1358 printf("\n[%s]\n", architecture
);
1362 for (j
=0; j
< count
; j
++) {
1363 display_print_driver1(&info
[j
].info1
);
1367 for (j
=0; j
< count
; j
++) {
1368 display_print_driver2(&info
[j
].info2
);
1372 for (j
=0; j
< count
; j
++) {
1373 display_print_driver3(&info
[j
].info3
);
1377 for (j
=0; j
< count
; j
++) {
1378 display_print_driver4(&info
[j
].info4
);
1382 for (j
=0; j
< count
; j
++) {
1383 display_print_driver5(&info
[j
].info5
);
1387 for (j
=0; j
< count
; j
++) {
1388 display_print_driver6(&info
[j
].info6
);
1392 for (j
=0; j
< count
; j
++) {
1393 display_print_driver8(&info
[j
].info8
);
1397 printf("unknown info level %d\n", level
);
1398 return WERR_UNKNOWN_LEVEL
;
1404 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1405 TALLOC_CTX
*mem_ctx
,
1406 int argc
, const char **argv
)
1408 WERROR werror
= WERR_OK
;
1411 const char *architecture
= NULL
;
1414 printf("Usage: enumdrivers [level] [architecture]\n");
1419 level
= atoi(argv
[1]);
1423 architecture
= argv
[2];
1427 return enum_driver_by_architecture(cli
, mem_ctx
,
1432 /* loop through and print driver info level for each architecture */
1433 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1434 /* check to see if we already asked for this architecture string */
1436 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1440 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1441 archi_table
[i
].long_archi
,
1443 if (!W_ERROR_IS_OK(werror
)) {
1451 /****************************************************************************
1452 ****************************************************************************/
1454 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1456 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1459 /****************************************************************************
1460 ****************************************************************************/
1462 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1463 TALLOC_CTX
*mem_ctx
,
1464 int argc
, const char **argv
)
1468 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1471 union spoolss_DriverDirectoryInfo info
;
1475 printf("Usage: %s [environment]\n", argv
[0]);
1479 /* Get the arguments need to open the printer handle */
1485 /* Get the directory. Only use Info level 1 */
1487 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1488 cli
->srv_name_slash
,
1496 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1498 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1500 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1501 cli
->srv_name_slash
,
1511 if (W_ERROR_IS_OK(result
)) {
1512 display_printdriverdir_1(&info
.info1
);
1518 /****************************************************************************
1519 ****************************************************************************/
1521 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1522 struct spoolss_AddDriverInfo3
*info
,
1528 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1530 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1532 info
->version
= archi_table
[i
].version
;
1533 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1538 if (archi_table
[i
].long_archi
== NULL
)
1540 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1547 /**************************************************************************
1548 wrapper for strtok to get the next parameter from a delimited list.
1549 Needed to handle the empty parameter string denoted by "NULL"
1550 *************************************************************************/
1552 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1553 const char *delim
, const char **dest
,
1558 /* get the next token */
1559 ptr
= strtok_r(str
, delim
, saveptr
);
1561 /* a string of 'NULL' is used to represent an empty
1562 parameter because two consecutive delimiters
1563 will not return an empty string. See man strtok(3)
1565 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1570 *dest
= talloc_strdup(mem_ctx
, ptr
);
1576 /********************************************************************************
1577 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1578 string in the form of
1579 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1580 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1581 <Default Data Type>:<Comma Separated list of Files>
1582 *******************************************************************************/
1584 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1589 char *saveptr
= NULL
;
1590 struct spoolss_StringArray
*deps
;
1591 const char **file_array
= NULL
;
1594 /* fill in the UNISTR fields */
1595 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1596 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1597 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1598 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1599 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1600 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1601 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1603 /* <Comma Separated List of Dependent Files> */
1604 /* save the beginning of the string */
1605 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1608 /* begin to strip out each filename */
1609 str
= strtok_r(str
, ",", &saveptr
);
1611 /* no dependent files, we are done */
1616 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1621 while (str
!= NULL
) {
1622 add_string_to_array(deps
, str
, &file_array
, &count
);
1623 str
= strtok_r(NULL
, ",", &saveptr
);
1626 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1627 if (!deps
->string
) {
1631 for (i
=0; i
< count
; i
++) {
1632 deps
->string
[i
] = file_array
[i
];
1635 r
->dependent_files
= deps
;
1640 /****************************************************************************
1641 ****************************************************************************/
1643 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1644 TALLOC_CTX
*mem_ctx
,
1645 int argc
, const char **argv
)
1650 struct spoolss_AddDriverInfoCtr info_ctr
;
1651 struct spoolss_AddDriverInfo3 info3
;
1655 /* parse the command arguments */
1656 if (argc
!= 3 && argc
!= 4)
1658 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1659 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1660 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1661 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1662 printf ("\t[version]\n");
1667 /* Fill in the spoolss_AddDriverInfo3 struct */
1670 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1672 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1673 return WERR_INVALID_PARAM
;
1676 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1678 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1679 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1681 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1682 return WERR_INVALID_PARAM
;
1685 /* if printer driver version specified, override the default version
1686 * used by the architecture. This allows installation of Windows
1687 * 2000 (version 3) printer drivers. */
1690 info3
.version
= atoi(argv
[3]);
1694 info_ctr
.level
= level
;
1695 info_ctr
.info
.info3
= &info3
;
1697 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1698 cli
->srv_name_slash
,
1701 if (!NT_STATUS_IS_OK(status
)) {
1702 return ntstatus_to_werror(status
);
1704 if (W_ERROR_IS_OK(result
)) {
1705 printf ("Printer Driver %s successfully installed.\n",
1713 /****************************************************************************
1714 ****************************************************************************/
1716 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1717 TALLOC_CTX
*mem_ctx
,
1718 int argc
, const char **argv
)
1721 struct spoolss_SetPrinterInfoCtr info_ctr
;
1722 struct spoolss_SetPrinterInfo2 info2
;
1724 /* parse the command arguments */
1727 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1731 /* Fill in the DRIVER_INFO_2 struct */
1734 info2
.printername
= argv
[1];
1735 info2
.drivername
= argv
[3];
1736 info2
.sharename
= argv
[2];
1737 info2
.portname
= argv
[4];
1738 info2
.comment
= "Created by rpcclient";
1739 info2
.printprocessor
= "winprint";
1740 info2
.datatype
= "RAW";
1741 info2
.devmode_ptr
= 0;
1742 info2
.secdesc_ptr
= 0;
1743 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1745 info2
.defaultpriority
= 0;
1746 info2
.starttime
= 0;
1747 info2
.untiltime
= 0;
1749 /* These three fields must not be used by AddPrinter()
1750 as defined in the MS Platform SDK documentation..
1754 info2.averageppm = 0;
1758 info_ctr
.info
.info2
= &info2
;
1760 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1762 if (W_ERROR_IS_OK(result
))
1763 printf ("Printer %s successfully installed.\n", argv
[1]);
1768 /****************************************************************************
1769 ****************************************************************************/
1771 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1772 TALLOC_CTX
*mem_ctx
,
1773 int argc
, const char **argv
)
1775 struct policy_handle pol
;
1779 const char *printername
;
1780 union spoolss_PrinterInfo info
;
1781 struct spoolss_SetPrinterInfoCtr info_ctr
;
1782 struct spoolss_SetPrinterInfo2 info2
;
1783 struct spoolss_DevmodeContainer devmode_ctr
;
1784 struct sec_desc_buf secdesc_ctr
;
1786 ZERO_STRUCT(devmode_ctr
);
1787 ZERO_STRUCT(secdesc_ctr
);
1789 /* parse the command arguments */
1792 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1796 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1798 /* Get a printer handle */
1800 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1804 if (!W_ERROR_IS_OK(result
))
1807 /* Get printer info */
1809 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1814 if (!W_ERROR_IS_OK(result
)) {
1815 printf ("Unable to retrieve printer information!\n");
1819 /* Set the printer driver */
1821 info2
.servername
= info
.info2
.servername
;
1822 info2
.printername
= info
.info2
.printername
;
1823 info2
.sharename
= info
.info2
.sharename
;
1824 info2
.portname
= info
.info2
.portname
;
1825 info2
.drivername
= argv
[2];
1826 info2
.comment
= info
.info2
.comment
;
1827 info2
.location
= info
.info2
.location
;
1828 info2
.devmode_ptr
= 0;
1829 info2
.sepfile
= info
.info2
.sepfile
;
1830 info2
.printprocessor
= info
.info2
.printprocessor
;
1831 info2
.datatype
= info
.info2
.datatype
;
1832 info2
.parameters
= info
.info2
.parameters
;
1833 info2
.secdesc_ptr
= 0;
1834 info2
.attributes
= info
.info2
.attributes
;
1835 info2
.priority
= info
.info2
.priority
;
1836 info2
.defaultpriority
= info
.info2
.defaultpriority
;
1837 info2
.starttime
= info
.info2
.starttime
;
1838 info2
.untiltime
= info
.info2
.untiltime
;
1839 info2
.status
= info
.info2
.status
;
1840 info2
.cjobs
= info
.info2
.cjobs
;
1841 info2
.averageppm
= info
.info2
.averageppm
;
1844 info_ctr
.info
.info2
= &info2
;
1846 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1853 if (!W_ERROR_IS_OK(result
)) {
1854 printf("SetPrinter call failed!\n");
1858 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1863 if (is_valid_policy_hnd(&pol
))
1864 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1870 /****************************************************************************
1871 ****************************************************************************/
1873 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1874 TALLOC_CTX
*mem_ctx
,
1875 int argc
, const char **argv
)
1877 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1883 const char *arch
= NULL
;
1884 uint32_t delete_flags
= 0;
1886 /* parse the command arguments */
1887 if (argc
< 2 || argc
> 4) {
1888 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1895 vers
= atoi (argv
[3]);
1898 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1901 /* delete the driver for all architectures */
1902 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1904 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1907 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1910 /* make the call to remove the driver */
1911 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1912 cli
->srv_name_slash
,
1913 archi_table
[i
].long_archi
,
1916 archi_table
[i
].version
,
1919 if ( !W_ERROR_IS_OK(result
) )
1921 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1922 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1923 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1928 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1929 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1938 /****************************************************************************
1939 ****************************************************************************/
1941 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1942 TALLOC_CTX
*mem_ctx
,
1943 int argc
, const char **argv
)
1945 WERROR result
= WERR_OK
;
1949 /* parse the command arguments */
1951 printf ("Usage: %s <driver>\n", argv
[0]);
1955 /* delete the driver for all architectures */
1956 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1957 /* make the call to remove the driver */
1958 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1959 cli
->srv_name_slash
,
1960 archi_table
[i
].long_archi
,
1963 if (!NT_STATUS_IS_OK(status
)) {
1966 if ( !W_ERROR_IS_OK(result
) ) {
1967 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1968 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1969 argv
[1], archi_table
[i
].long_archi
,
1973 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1974 archi_table
[i
].long_archi
);
1981 /****************************************************************************
1982 ****************************************************************************/
1984 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1985 TALLOC_CTX
*mem_ctx
,
1986 int argc
, const char **argv
)
1990 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1993 union spoolss_PrintProcessorDirectoryInfo info
;
1996 /* parse the command arguments */
1998 printf ("Usage: %s [environment]\n", argv
[0]);
2003 environment
= argv
[1];
2006 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
2007 cli
->srv_name_slash
,
2015 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2017 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2019 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
2020 cli
->srv_name_slash
,
2030 if (W_ERROR_IS_OK(result
)) {
2031 printf("%s\n", info
.info1
.directory_name
);
2037 /****************************************************************************
2038 ****************************************************************************/
2040 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2041 int argc
, const char **argv
)
2043 struct policy_handle handle
;
2046 const char *printername
;
2047 union spoolss_AddFormInfo info
;
2048 struct spoolss_AddFormInfo1 info1
;
2049 struct spoolss_AddFormInfo2 info2
;
2052 /* Parse the command arguments */
2054 if (argc
< 3 || argc
> 5) {
2055 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2059 /* Get a printer handle */
2061 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2063 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2067 if (!W_ERROR_IS_OK(werror
))
2070 /* Dummy up some values for the form data */
2073 level
= atoi(argv
[3]);
2078 info1
.flags
= SPOOLSS_FORM_USER
;
2079 info1
.form_name
= argv
[2];
2080 info1
.size
.width
= 100;
2081 info1
.size
.height
= 100;
2082 info1
.area
.left
= 0;
2083 info1
.area
.top
= 10;
2084 info1
.area
.right
= 20;
2085 info1
.area
.bottom
= 30;
2087 info
.info1
= &info1
;
2091 info2
.flags
= SPOOLSS_FORM_USER
;
2092 info2
.form_name
= argv
[2];
2093 info2
.size
.width
= 100;
2094 info2
.size
.height
= 100;
2095 info2
.area
.left
= 0;
2096 info2
.area
.top
= 10;
2097 info2
.area
.right
= 20;
2098 info2
.area
.bottom
= 30;
2099 info2
.keyword
= argv
[2];
2100 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2101 info2
.mui_dll
= NULL
;
2102 info2
.ressource_id
= 0;
2103 info2
.display_name
= argv
[2];
2106 info
.info2
= &info2
;
2114 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
2121 if (is_valid_policy_hnd(&handle
))
2122 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2127 /****************************************************************************
2128 ****************************************************************************/
2130 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2131 int argc
, const char **argv
)
2133 struct policy_handle handle
;
2136 const char *printername
;
2137 union spoolss_AddFormInfo info
;
2138 struct spoolss_AddFormInfo1 info1
;
2140 /* Parse the command arguments */
2143 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2147 /* Get a printer handle */
2149 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2151 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2153 SEC_FLAG_MAXIMUM_ALLOWED
,
2155 if (!W_ERROR_IS_OK(werror
))
2158 /* Dummy up some values for the form data */
2160 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2161 info1
.size
.width
= 100;
2162 info1
.size
.height
= 100;
2163 info1
.area
.left
= 0;
2164 info1
.area
.top
= 1000;
2165 info1
.area
.right
= 2000;
2166 info1
.area
.bottom
= 3000;
2167 info1
.form_name
= argv
[2];
2169 info
.info1
= &info1
;
2173 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
2181 if (is_valid_policy_hnd(&handle
))
2182 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2187 /****************************************************************************
2188 ****************************************************************************/
2190 static const char *get_form_flag(int form_flag
)
2192 switch (form_flag
) {
2193 case SPOOLSS_FORM_USER
:
2195 case SPOOLSS_FORM_BUILTIN
:
2196 return "FORM_BUILTIN";
2197 case SPOOLSS_FORM_PRINTER
:
2198 return "FORM_PRINTER";
2204 /****************************************************************************
2205 ****************************************************************************/
2207 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2210 "\tflag: %s (%d)\n" \
2211 "\twidth: %d, length: %d\n" \
2212 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2213 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2214 r
->size
.width
, r
->size
.height
,
2215 r
->area
.left
, r
->area
.right
,
2216 r
->area
.top
, r
->area
.bottom
);
2219 /****************************************************************************
2220 ****************************************************************************/
2222 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2225 "\tflag: %s (%d)\n" \
2226 "\twidth: %d, length: %d\n" \
2227 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2228 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2229 r
->size
.width
, r
->size
.height
,
2230 r
->area
.left
, r
->area
.right
,
2231 r
->area
.top
, r
->area
.bottom
);
2232 printf("\tkeyword: %s\n", r
->keyword
);
2233 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2234 printf("\tmui_dll: %s\n", r
->mui_dll
);
2235 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2236 printf("\tdisplay_name: %s\n", r
->display_name
);
2237 printf("\tlang_id: %d\n", r
->lang_id
);
2241 /****************************************************************************
2242 ****************************************************************************/
2244 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2245 int argc
, const char **argv
)
2247 struct policy_handle handle
;
2250 const char *printername
;
2252 uint32_t offered
= 0;
2253 union spoolss_FormInfo info
;
2257 /* Parse the command arguments */
2259 if (argc
< 3 || argc
> 5) {
2260 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2264 /* Get a printer handle */
2266 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2268 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2270 SEC_FLAG_MAXIMUM_ALLOWED
,
2272 if (!W_ERROR_IS_OK(werror
))
2276 level
= atoi(argv
[3]);
2281 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2290 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2291 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2293 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2304 if (!NT_STATUS_IS_OK(status
)) {
2310 display_form_info1(&info
.info1
);
2313 display_form_info2(&info
.info2
);
2318 if (is_valid_policy_hnd(&handle
))
2319 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2324 /****************************************************************************
2325 ****************************************************************************/
2327 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2328 TALLOC_CTX
*mem_ctx
, int argc
,
2331 struct policy_handle handle
;
2334 const char *printername
;
2336 /* Parse the command arguments */
2339 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2343 /* Get a printer handle */
2345 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2347 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2349 SEC_FLAG_MAXIMUM_ALLOWED
,
2351 if (!W_ERROR_IS_OK(werror
))
2354 /* Delete the form */
2356 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2360 if (!NT_STATUS_IS_OK(status
)) {
2361 return ntstatus_to_werror(status
);
2365 if (is_valid_policy_hnd(&handle
))
2366 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2371 /****************************************************************************
2372 ****************************************************************************/
2374 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2375 TALLOC_CTX
*mem_ctx
, int argc
,
2378 struct policy_handle handle
;
2380 const char *printername
;
2381 uint32_t num_forms
, level
= 1, i
;
2382 union spoolss_FormInfo
*forms
;
2384 /* Parse the command arguments */
2386 if (argc
< 2 || argc
> 4) {
2387 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2391 /* Get a printer handle */
2393 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2395 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2397 SEC_FLAG_MAXIMUM_ALLOWED
,
2399 if (!W_ERROR_IS_OK(werror
))
2403 level
= atoi(argv
[2]);
2406 /* Enumerate forms */
2408 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2415 if (!W_ERROR_IS_OK(werror
))
2418 /* Display output */
2420 for (i
= 0; i
< num_forms
; i
++) {
2423 display_form_info1(&forms
[i
].info1
);
2426 display_form_info2(&forms
[i
].info2
);
2432 if (is_valid_policy_hnd(&handle
))
2433 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2438 /****************************************************************************
2439 ****************************************************************************/
2441 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2442 TALLOC_CTX
*mem_ctx
,
2443 int argc
, const char **argv
)
2447 const char *printername
;
2448 struct policy_handle pol
;
2449 union spoolss_PrinterInfo info
;
2450 enum winreg_Type type
;
2451 union spoolss_PrinterData data
;
2454 /* parse the command arguments */
2456 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2457 " <value> <data>\n",
2462 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2466 if (strequal(argv
[2], "string")) {
2470 if (strequal(argv
[2], "binary")) {
2474 if (strequal(argv
[2], "dword")) {
2478 if (strequal(argv
[2], "multistring")) {
2479 type
= REG_MULTI_SZ
;
2482 if (type
== REG_NONE
) {
2483 printf("Unknown data type: %s\n", argv
[2]);
2484 result
= WERR_INVALID_PARAM
;
2488 /* get a printer handle */
2490 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2492 SEC_FLAG_MAXIMUM_ALLOWED
,
2494 if (!W_ERROR_IS_OK(result
)) {
2498 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2503 if (!W_ERROR_IS_OK(result
)) {
2507 printf("%s\n", current_timestring(mem_ctx
, true));
2508 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2510 /* Set the printer data */
2514 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2515 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2518 data
.value
= strtoul(argv
[4], NULL
, 10);
2521 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2523 case REG_MULTI_SZ
: {
2525 const char **strings
= NULL
;
2527 for (i
=4; i
<argc
; i
++) {
2528 if (strcmp(argv
[i
], "NULL") == 0) {
2531 if (!add_string_to_array(mem_ctx
, argv
[i
],
2534 result
= WERR_NOMEM
;
2538 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2539 if (!data
.string_array
) {
2540 result
= WERR_NOMEM
;
2543 for (i
=0; i
< num_strings
; i
++) {
2544 data
.string_array
[i
] = strings
[i
];
2549 printf("Unknown data type: %s\n", argv
[2]);
2550 result
= WERR_INVALID_PARAM
;
2554 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2555 if (!W_ERROR_IS_OK(result
)) {
2559 status
= rpccli_spoolss_SetPrinterData(cli
, mem_ctx
,
2561 argv
[3], /* value_name */
2566 if (!W_ERROR_IS_OK(result
)) {
2567 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2570 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2572 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2577 if (!W_ERROR_IS_OK(result
)) {
2581 printf("%s\n", current_timestring(mem_ctx
, true));
2582 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2586 if (is_valid_policy_hnd(&pol
)) {
2587 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2593 /****************************************************************************
2594 ****************************************************************************/
2596 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2598 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2599 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2603 /****************************************************************************
2604 ****************************************************************************/
2606 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2608 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2609 r
->position
, r
->job_id
,
2610 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2611 r
->total_pages
, r
->size
);
2614 /****************************************************************************
2615 ****************************************************************************/
2617 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2619 printf("jobid[%d], next_jobid[%d]\n",
2620 r
->job_id
, r
->next_job_id
);
2623 /****************************************************************************
2624 ****************************************************************************/
2626 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2628 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2629 r
->position
, r
->job_id
,
2630 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2631 r
->total_pages
, r
->size
, r
->size_high
);
2634 /****************************************************************************
2635 ****************************************************************************/
2637 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2638 TALLOC_CTX
*mem_ctx
, int argc
,
2642 uint32_t level
= 1, count
, i
;
2643 const char *printername
;
2644 struct policy_handle hnd
;
2645 union spoolss_JobInfo
*info
;
2647 if (argc
< 2 || argc
> 3) {
2648 printf("Usage: %s printername [level]\n", argv
[0]);
2653 level
= atoi(argv
[2]);
2656 /* Open printer handle */
2658 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2660 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2662 SEC_FLAG_MAXIMUM_ALLOWED
,
2664 if (!W_ERROR_IS_OK(result
))
2667 /* Enumerate ports */
2669 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2677 if (!W_ERROR_IS_OK(result
)) {
2681 for (i
= 0; i
< count
; i
++) {
2684 display_job_info1(&info
[i
].info1
);
2687 display_job_info2(&info
[i
].info2
);
2690 d_printf("unknown info level %d\n", level
);
2696 if (is_valid_policy_hnd(&hnd
)) {
2697 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2703 /****************************************************************************
2704 ****************************************************************************/
2706 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2707 TALLOC_CTX
*mem_ctx
, int argc
,
2711 const char *printername
;
2712 struct policy_handle hnd
;
2715 union spoolss_JobInfo info
;
2717 if (argc
< 3 || argc
> 4) {
2718 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2722 job_id
= atoi(argv
[2]);
2725 level
= atoi(argv
[3]);
2728 /* Open printer handle */
2730 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2732 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2734 SEC_FLAG_MAXIMUM_ALLOWED
,
2736 if (!W_ERROR_IS_OK(result
)) {
2740 /* Enumerate ports */
2742 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2749 if (!W_ERROR_IS_OK(result
)) {
2755 display_job_info1(&info
.info1
);
2758 display_job_info2(&info
.info2
);
2761 display_job_info3(&info
.info3
);
2764 display_job_info4(&info
.info4
);
2767 d_printf("unknown info level %d\n", level
);
2772 if (is_valid_policy_hnd(&hnd
)) {
2773 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2779 /****************************************************************************
2780 ****************************************************************************/
2782 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2783 TALLOC_CTX
*mem_ctx
, int argc
,
2788 const char *printername
;
2789 struct policy_handle hnd
;
2791 enum spoolss_JobControl command
;
2794 printf("Usage: %s printername job_id command\n", argv
[0]);
2798 job_id
= atoi(argv
[2]);
2799 command
= atoi(argv
[3]);
2801 /* Open printer handle */
2803 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2805 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2807 SEC_FLAG_MAXIMUM_ALLOWED
,
2809 if (!W_ERROR_IS_OK(result
)) {
2815 status
= rpccli_spoolss_SetJob(cli
, mem_ctx
,
2822 if (!W_ERROR_IS_OK(result
)) {
2827 if (is_valid_policy_hnd(&hnd
)) {
2828 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2834 /****************************************************************************
2835 ****************************************************************************/
2837 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2838 TALLOC_CTX
*mem_ctx
, int argc
,
2844 const char *printername
;
2845 struct policy_handle hnd
;
2846 uint32_t value_offered
= 0;
2847 const char *value_name
= NULL
;
2848 uint32_t value_needed
;
2849 enum winreg_Type type
;
2850 uint8_t *data
= NULL
;
2851 uint32_t data_offered
= 0;
2852 uint32_t data_needed
;
2855 printf("Usage: %s printername\n", argv
[0]);
2859 /* Open printer handle */
2861 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2863 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2865 SEC_FLAG_MAXIMUM_ALLOWED
,
2867 if (!W_ERROR_IS_OK(result
)) {
2871 /* Enumerate data */
2873 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2885 data_offered
= data_needed
;
2886 value_offered
= value_needed
;
2887 data
= talloc_zero_array(mem_ctx
, uint8_t, data_needed
);
2888 value_name
= talloc_zero_array(mem_ctx
, char, value_needed
);
2890 while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2892 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2903 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2904 struct regval_blob
*v
;
2906 v
= regval_compose(talloc_tos(),
2912 result
= WERR_NOMEM
;
2916 display_reg_value(v
);
2921 if (W_ERROR_V(result
) == ERRnomoreitems
) {
2922 result
= W_ERROR(ERRsuccess
);
2926 if (is_valid_policy_hnd(&hnd
)) {
2927 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2933 /****************************************************************************
2934 ****************************************************************************/
2936 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2937 TALLOC_CTX
*mem_ctx
, int argc
,
2942 const char *printername
;
2943 struct policy_handle hnd
;
2945 struct spoolss_PrinterEnumValues
*info
;
2948 printf("Usage: %s printername <keyname>\n", argv
[0]);
2952 /* Open printer handle */
2954 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2956 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2958 SEC_FLAG_MAXIMUM_ALLOWED
,
2960 if (!W_ERROR_IS_OK(result
)) {
2964 /* Enumerate subkeys */
2966 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
2972 if (!W_ERROR_IS_OK(result
)) {
2976 for (i
=0; i
< count
; i
++) {
2977 display_printer_data(info
[i
].value_name
,
2980 info
[i
].data
->length
);
2984 if (is_valid_policy_hnd(&hnd
)) {
2985 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2991 /****************************************************************************
2992 ****************************************************************************/
2994 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
2995 TALLOC_CTX
*mem_ctx
, int argc
,
2999 const char *printername
;
3000 const char *keyname
= NULL
;
3001 struct policy_handle hnd
;
3002 const char **key_buffer
= NULL
;
3004 uint32_t offered
= 0;
3006 if (argc
< 2 || argc
> 4) {
3007 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3018 offered
= atoi(argv
[3]);
3021 /* Open printer handle */
3023 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3025 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3027 SEC_FLAG_MAXIMUM_ALLOWED
,
3029 if (!W_ERROR_IS_OK(result
)) {
3033 /* Enumerate subkeys */
3035 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3041 if (!W_ERROR_IS_OK(result
)) {
3045 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3046 printf("%s\n", key_buffer
[i
]);
3051 if (is_valid_policy_hnd(&hnd
)) {
3052 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3058 /****************************************************************************
3059 ****************************************************************************/
3061 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3062 TALLOC_CTX
*mem_ctx
, int argc
,
3065 const char *printername
;
3066 const char *clientname
;
3067 struct policy_handle hnd
;
3070 struct spoolss_NotifyOption option
;
3073 printf("Usage: %s printername\n", argv
[0]);
3080 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3082 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3084 SEC_FLAG_MAXIMUM_ALLOWED
,
3086 if (!W_ERROR_IS_OK(result
)) {
3087 printf("Error opening %s\n", argv
[1]);
3091 /* Create spool options */
3096 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3097 if (option
.types
== NULL
) {
3098 result
= WERR_NOMEM
;
3102 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3103 option
.types
[0].count
= 1;
3104 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3105 if (option
.types
[0].fields
== NULL
) {
3106 result
= WERR_NOMEM
;
3109 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3111 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3112 option
.types
[1].count
= 1;
3113 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3114 if (option
.types
[1].fields
== NULL
) {
3115 result
= WERR_NOMEM
;
3118 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3120 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
3122 result
= WERR_NOMEM
;
3128 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
3136 if (!W_ERROR_IS_OK(result
)) {
3137 printf("Error rffpcnex %s\n", argv
[1]);
3142 if (is_valid_policy_hnd(&hnd
))
3143 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3148 /****************************************************************************
3149 ****************************************************************************/
3151 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3152 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3154 union spoolss_PrinterInfo info1
, info2
;
3156 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3158 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3159 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3164 if ( !W_ERROR_IS_OK(werror
) ) {
3165 printf("failed (%s)\n", win_errstr(werror
));
3166 talloc_destroy(mem_ctx
);
3171 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3172 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3177 if ( !W_ERROR_IS_OK(werror
) ) {
3178 printf("failed (%s)\n", win_errstr(werror
));
3179 talloc_destroy(mem_ctx
);
3184 talloc_destroy(mem_ctx
);
3189 /****************************************************************************
3190 ****************************************************************************/
3192 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3193 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3195 union spoolss_PrinterInfo info1
, info2
;
3197 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3198 struct security_descriptor
*sd1
, *sd2
;
3202 printf("Retrieving printer security for %s...", cli1
->desthost
);
3203 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3208 if ( !W_ERROR_IS_OK(werror
) ) {
3209 printf("failed (%s)\n", win_errstr(werror
));
3215 printf("Retrieving printer security for %s...", cli2
->desthost
);
3216 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3221 if ( !W_ERROR_IS_OK(werror
) ) {
3222 printf("failed (%s)\n", win_errstr(werror
));
3231 sd1
= info1
.info3
.secdesc
;
3232 sd2
= info2
.info3
.secdesc
;
3234 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3235 printf("NULL secdesc!\n");
3240 if (!security_descriptor_equal( sd1
, sd2
) ) {
3241 printf("Security Descriptors *not* equal!\n");
3246 printf("Security descriptors match\n");
3249 talloc_destroy(mem_ctx
);
3254 /****************************************************************************
3255 ****************************************************************************/
3257 extern struct user_auth_info
*rpcclient_auth_info
;
3259 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3260 TALLOC_CTX
*mem_ctx
, int argc
,
3263 const char *printername
;
3264 char *printername_path
= NULL
;
3265 struct cli_state
*cli_server2
= NULL
;
3266 struct rpc_pipe_client
*cli2
= NULL
;
3267 struct policy_handle hPrinter1
, hPrinter2
;
3272 printf("Usage: %s <printer> <server>\n", argv
[0]);
3276 printername
= argv
[1];
3278 /* first get the connection to the remote server */
3280 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
3283 get_cmdline_auth_info_username(rpcclient_auth_info
),
3285 get_cmdline_auth_info_password(rpcclient_auth_info
),
3286 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3287 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
3289 if ( !NT_STATUS_IS_OK(nt_status
) )
3290 return WERR_GENERAL_FAILURE
;
3292 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
.syntax_id
,
3294 if (!NT_STATUS_IS_OK(nt_status
)) {
3295 printf("failed to open spoolss pipe on server %s (%s)\n",
3296 argv
[2], nt_errstr(nt_status
));
3297 return WERR_GENERAL_FAILURE
;
3300 /* now open up both printers */
3302 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3304 printf("Opening %s...", printername_path
);
3306 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3310 if ( !W_ERROR_IS_OK(werror
) ) {
3311 printf("failed (%s)\n", win_errstr(werror
));
3316 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3318 printf("Opening %s...", printername_path
);
3319 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3323 if ( !W_ERROR_IS_OK(werror
) ) {
3324 printf("failed (%s)\n", win_errstr(werror
));
3329 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3330 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3332 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3339 printf("Closing printers...");
3340 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3341 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3344 /* close the second remote connection */
3346 cli_shutdown( cli_server2
);
3350 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3352 printf("print_processor_name: %s\n", r
->print_processor_name
);
3355 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3356 TALLOC_CTX
*mem_ctx
, int argc
,
3360 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3361 uint32_t num_procs
, level
= 1, i
;
3362 union spoolss_PrintProcessorInfo
*procs
;
3364 /* Parse the command arguments */
3366 if (argc
< 1 || argc
> 4) {
3367 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3372 environment
= argv
[1];
3376 level
= atoi(argv
[2]);
3379 /* Enumerate Print Processors */
3381 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3382 cli
->srv_name_slash
,
3388 if (!W_ERROR_IS_OK(werror
))
3391 /* Display output */
3393 for (i
= 0; i
< num_procs
; i
++) {
3396 display_proc_info1(&procs
[i
].info1
);
3405 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3407 printf("name_array: %s\n", r
->name_array
);
3410 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3411 TALLOC_CTX
*mem_ctx
, int argc
,
3415 const char *print_processor_name
= "winprint";
3416 uint32_t num_procs
, level
= 1, i
;
3417 union spoolss_PrintProcDataTypesInfo
*procs
;
3419 /* Parse the command arguments */
3421 if (argc
< 1 || argc
> 4) {
3422 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3427 print_processor_name
= argv
[1];
3431 level
= atoi(argv
[2]);
3434 /* Enumerate Print Processor Data Types */
3436 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3437 cli
->srv_name_slash
,
3438 print_processor_name
,
3443 if (!W_ERROR_IS_OK(werror
))
3446 /* Display output */
3448 for (i
= 0; i
< num_procs
; i
++) {
3451 display_proc_data_types_info1(&procs
[i
].info1
);
3460 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3462 printf("monitor_name: %s\n", r
->monitor_name
);
3465 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3467 printf("monitor_name: %s\n", r
->monitor_name
);
3468 printf("environment: %s\n", r
->environment
);
3469 printf("dll_name: %s\n", r
->dll_name
);
3472 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3473 TALLOC_CTX
*mem_ctx
, int argc
,
3477 uint32_t count
, level
= 1, i
;
3478 union spoolss_MonitorInfo
*info
;
3480 /* Parse the command arguments */
3483 printf("Usage: %s [level]\n", argv
[0]);
3488 level
= atoi(argv
[1]);
3491 /* Enumerate Print Monitors */
3493 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3494 cli
->srv_name_slash
,
3499 if (!W_ERROR_IS_OK(werror
)) {
3503 /* Display output */
3505 for (i
= 0; i
< count
; i
++) {
3508 display_monitor1(&info
[i
].info1
);
3511 display_monitor2(&info
[i
].info2
);
3520 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3521 TALLOC_CTX
*mem_ctx
, int argc
,
3526 struct policy_handle handle
, gdi_handle
;
3527 const char *printername
;
3528 struct spoolss_DevmodeContainer devmode_ctr
;
3530 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3532 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3534 SEC_FLAG_MAXIMUM_ALLOWED
,
3536 if (!W_ERROR_IS_OK(result
)) {
3540 ZERO_STRUCT(devmode_ctr
);
3542 status
= rpccli_spoolss_CreatePrinterIC(cli
, mem_ctx
,
3547 if (!W_ERROR_IS_OK(result
)) {
3552 if (is_valid_policy_hnd(&gdi_handle
)) {
3553 rpccli_spoolss_DeletePrinterIC(cli
, mem_ctx
, &gdi_handle
, NULL
);
3555 if (is_valid_policy_hnd(&handle
)) {
3556 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
3562 /* List of commands exported by this module */
3563 struct cmd_set spoolss_commands
[] = {
3567 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a print driver", "" },
3568 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a printer", "" },
3569 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver", "" },
3570 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver with files", "" },
3571 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data", "" },
3572 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data for a key", "" },
3573 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer keys", "" },
3574 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate print jobs", "" },
3575 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print job", "" },
3576 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set print job", "" },
3577 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer ports", "" },
3578 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate installed printer drivers", "" },
3579 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printers", "" },
3580 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver data", "" },
3581 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer driver data with keyname", ""},
3582 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver information", "" },
3583 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver upload directory", "" },
3584 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer info", "" },
3585 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3586 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer driver", "" },
3587 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print processor directory", "" },
3588 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add form", "" },
3589 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set form", "" },
3590 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get form", "" },
3591 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete form", "" },
3592 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate forms", "" },
3593 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer comment", "" },
3594 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printername", "" },
3595 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set REG_SZ printer data", "" },
3596 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Rffpcnex test", "" },
3597 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
.syntax_id
, NULL
, "Printer comparison test", "" },
3598 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processors", "" },
3599 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processor Data Types", "" },
3600 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Monitors", "" },
3601 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
.syntax_id
, NULL
, "Create Printer IC", "" },