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/ndr_spoolss_c.h"
28 #include "rpc_client/cli_spoolss.h"
29 #include "rpc_client/init_spoolss.h"
30 #include "registry/reg_objects.h"
31 #include "nt_printing.h"
32 #include "../libcli/security/display_sec.h"
33 #include "../libcli/security/security_descriptor.h"
34 #include "../libcli/registry/util_reg.h"
35 #include "libsmb/libsmb.h"
37 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
39 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
40 _cli->srv_name_slash, _arg); \
41 W_ERROR_HAVE_NO_MEMORY(_printername); \
44 /* The version int is used by getdrivers. Note that
45 all architecture strings that support mutliple
46 versions must be grouped together since enumdrivers
47 uses this property to prevent issuing multiple
48 enumdriver calls for the same arch */
51 static const struct print_architecture_table_node archi_table
[]= {
53 {"Windows 4.0", "WIN40", 0 },
54 {"Windows NT x86", "W32X86", 2 },
55 {"Windows NT x86", "W32X86", 3 },
56 {"Windows NT R4000", "W32MIPS", 2 },
57 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
58 {"Windows NT PowerPC", "W32PPC", 2 },
59 {"Windows IA64", "IA64", 3 },
60 {"Windows x64", "x64", 3 },
67 * rpcclient module for SPOOLSS rpc pipe.
69 * This generally just parses and checks command lines, and then calls
70 * a cli_spoolss function.
73 /****************************************************************************
74 function to do the mapping between the long architecture name and
76 ****************************************************************************/
78 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
82 DEBUG(107,("Getting architecture dependent directory\n"));
85 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
86 strcasecmp_m(long_archi
, archi_table
[i
].long_archi
) );
88 if (archi_table
[i
].long_archi
==NULL
) {
89 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
93 /* this might be client code - but shouldn't this be an fstrcpy etc? */
96 DEBUGADD(108,("index: [%d]\n", i
));
97 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
98 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
100 return archi_table
[i
].short_archi
;
103 /****************************************************************************
104 ****************************************************************************/
106 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
108 int argc
, const char **argv
)
111 struct policy_handle hnd
;
112 uint32_t access_mask
= PRINTER_ALL_ACCESS
;
113 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
116 printf("Usage: %s <printername> [access_mask]\n", argv
[0]);
121 sscanf(argv
[2], "%x", &access_mask
);
124 /* Open the printer handle */
126 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
130 if (W_ERROR_IS_OK(werror
)) {
131 printf("Printer %s opened successfully\n", argv
[1]);
132 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &werror
);
134 if (!W_ERROR_IS_OK(werror
)) {
135 printf("Error closing printer handle! (%s)\n",
136 get_dos_error_msg(werror
));
143 /****************************************************************************
144 ****************************************************************************/
146 static WERROR
cmd_spoolss_open_printer(struct rpc_pipe_client
*cli
,
148 int argc
, const char **argv
)
151 struct policy_handle hnd
;
152 uint32_t access_mask
= PRINTER_ALL_ACCESS
;
154 struct spoolss_DevmodeContainer devmode_ctr
;
155 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
157 ZERO_STRUCT(devmode_ctr
);
160 printf("Usage: %s <printername> [access_mask]\n", argv
[0]);
165 sscanf(argv
[2], "%x", &access_mask
);
168 /* Open the printer handle */
170 status
= dcerpc_spoolss_OpenPrinter(b
, mem_ctx
,
177 if (!NT_STATUS_IS_OK(status
)) {
178 return ntstatus_to_werror(status
);
180 if (W_ERROR_IS_OK(werror
)) {
181 printf("Printer %s opened successfully\n", argv
[1]);
182 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &werror
);
184 if (!W_ERROR_IS_OK(werror
)) {
185 printf("Error closing printer handle! (%s)\n",
186 get_dos_error_msg(werror
));
193 /****************************************************************************
194 ****************************************************************************/
196 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
201 printf("\tprintername:[%s]\n", r
->printername
);
202 printf("\tservername:[%s]\n", r
->servername
);
203 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
204 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
205 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
206 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
207 r
->time
.day
, r
->time
.day_of_week
);
208 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
209 r
->time
.second
, r
->time
.millisecond
);
211 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
212 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
214 printf("\tversion:[0x%x]\n", r
->version
);
215 printf("\tfree_build:[0x%x]\n", r
->free_build
);
216 printf("\tspooling:[0x%x]\n", r
->spooling
);
217 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
218 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
219 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
220 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
221 printf("\tjob_error:[0x%x]\n", r
->job_error
);
222 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
223 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
224 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
225 printf("\tchange_id:[0x%x]\n", r
->change_id
);
226 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
227 printf("\tstatus:[0x%x]\n", r
->status
);
228 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
229 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
230 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
231 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
232 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
233 printf("\treserved2:[0x%x]\n", r
->reserved2
);
234 printf("\treserved3:[0x%x]\n", r
->reserved3
);
239 /****************************************************************************
240 ****************************************************************************/
242 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
244 printf("\tflags:[0x%x]\n", r
->flags
);
245 printf("\tname:[%s]\n", r
->name
);
246 printf("\tdescription:[%s]\n", r
->description
);
247 printf("\tcomment:[%s]\n", r
->comment
);
252 /****************************************************************************
253 ****************************************************************************/
255 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
257 printf("\tservername:[%s]\n", r
->servername
);
258 printf("\tprintername:[%s]\n", r
->printername
);
259 printf("\tsharename:[%s]\n", r
->sharename
);
260 printf("\tportname:[%s]\n", r
->portname
);
261 printf("\tdrivername:[%s]\n", r
->drivername
);
262 printf("\tcomment:[%s]\n", r
->comment
);
263 printf("\tlocation:[%s]\n", r
->location
);
264 printf("\tsepfile:[%s]\n", r
->sepfile
);
265 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
266 printf("\tdatatype:[%s]\n", r
->datatype
);
267 printf("\tparameters:[%s]\n", r
->parameters
);
268 printf("\tattributes:[0x%x]\n", r
->attributes
);
269 printf("\tpriority:[0x%x]\n", r
->priority
);
270 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
271 printf("\tstarttime:[0x%x]\n", r
->starttime
);
272 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
273 printf("\tstatus:[0x%x]\n", r
->status
);
274 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
275 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
278 display_sec_desc(r
->secdesc
);
283 /****************************************************************************
284 ****************************************************************************/
286 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
288 display_sec_desc(r
->secdesc
);
293 /****************************************************************************
294 ****************************************************************************/
296 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
298 printf("\tservername:[%s]\n", r
->servername
);
299 printf("\tprintername:[%s]\n", r
->printername
);
300 printf("\tattributes:[0x%x]\n", r
->attributes
);
304 /****************************************************************************
305 ****************************************************************************/
307 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
309 printf("\tprintername:[%s]\n", r
->printername
);
310 printf("\tportname:[%s]\n", r
->portname
);
311 printf("\tattributes:[0x%x]\n", r
->attributes
);
312 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
313 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
317 /****************************************************************************
318 ****************************************************************************/
320 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
322 printf("\tstatus:[0x%x]\n", r
->status
);
326 /****************************************************************************
327 ****************************************************************************/
329 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
331 printf("\tguid:[%s]\n", r
->guid
);
332 printf("\taction:[0x%x]\n", r
->action
);
336 /****************************************************************************
337 ****************************************************************************/
339 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
341 int argc
, const char **argv
)
345 union spoolss_PrinterInfo
*info
;
348 uint32_t flags
= PRINTER_ENUM_LOCAL
;
351 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
356 level
= atoi(argv
[1]);
362 name
= cli
->srv_name_slash
;
366 flags
= atoi(argv
[3]);
369 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
376 if (W_ERROR_IS_OK(result
)) {
379 printf ("No printers returned.\n");
383 for (i
= 0; i
< count
; i
++) {
386 display_print_info0(&info
[i
].info0
);
389 display_print_info1(&info
[i
].info1
);
392 display_print_info2(&info
[i
].info2
);
395 display_print_info3(&info
[i
].info3
);
398 display_print_info4(&info
[i
].info4
);
401 display_print_info5(&info
[i
].info5
);
404 display_print_info6(&info
[i
].info6
);
407 printf("unknown info level %d\n", level
);
417 /****************************************************************************
418 ****************************************************************************/
420 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
422 printf("\tPort Name:\t[%s]\n", r
->port_name
);
425 /****************************************************************************
426 ****************************************************************************/
428 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
430 printf("\tPort Name:\t[%s]\n", r
->port_name
);
431 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
432 printf("\tDescription:\t[%s]\n", r
->description
);
433 printf("\tPort Type:\t" );
435 int comma
= 0; /* hack */
437 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
441 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
442 printf( "%sWrite", comma
? ", " : "" );
445 /* These two have slightly different interpretations
446 on 95/98/ME but I'm disregarding that for now */
447 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
448 printf( "%sRedirected", comma
? ", " : "" );
451 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
452 printf( "%sNet-Attached", comma
? ", " : "" );
456 printf( "[Unset]\n" );
458 printf("\tReserved:\t[%d]\n", r
->reserved
);
462 /****************************************************************************
463 ****************************************************************************/
465 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
466 TALLOC_CTX
*mem_ctx
, int argc
,
472 union spoolss_PortInfo
*info
;
475 printf("Usage: %s [level]\n", argv
[0]);
480 level
= atoi(argv
[1]);
483 /* Enumerate ports */
485 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
491 if (W_ERROR_IS_OK(result
)) {
494 for (i
= 0; i
< count
; i
++) {
497 display_port_info_1(&info
[i
].info1
);
500 display_port_info_2(&info
[i
].info2
);
503 printf("unknown info level %d\n", level
);
512 /****************************************************************************
513 ****************************************************************************/
515 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
517 int argc
, const char **argv
)
519 struct policy_handle pol
;
522 uint32_t info_level
= 2;
523 union spoolss_PrinterInfo info
;
524 struct spoolss_SetPrinterInfoCtr info_ctr
;
525 struct spoolss_SetPrinterInfo2 info2
;
526 const char *printername
, *comment
= NULL
;
527 struct spoolss_DevmodeContainer devmode_ctr
;
528 struct sec_desc_buf secdesc_ctr
;
529 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
531 if (argc
== 1 || argc
> 3) {
532 printf("Usage: %s printername comment\n", argv
[0]);
537 /* Open a printer handle */
542 ZERO_STRUCT(devmode_ctr
);
543 ZERO_STRUCT(secdesc_ctr
);
545 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
547 /* get a printer handle */
548 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
552 if (!W_ERROR_IS_OK(result
))
555 /* Get printer info */
556 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
561 if (!W_ERROR_IS_OK(result
))
565 /* Modify the comment. */
566 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
567 info2
.comment
= comment
;
570 info_ctr
.info
.info2
= &info2
;
572 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
579 if (!NT_STATUS_IS_OK(status
)) {
580 result
= ntstatus_to_werror(status
);
583 if (W_ERROR_IS_OK(result
))
584 printf("Success in setting comment.\n");
587 if (is_valid_policy_hnd(&pol
)) {
589 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
595 /****************************************************************************
596 ****************************************************************************/
598 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
600 int argc
, const char **argv
)
602 struct policy_handle pol
;
605 uint32_t info_level
= 2;
606 union spoolss_PrinterInfo info
;
607 const char *printername
,
608 *new_printername
= NULL
;
609 struct spoolss_SetPrinterInfoCtr info_ctr
;
610 struct spoolss_SetPrinterInfo2 info2
;
611 struct spoolss_DevmodeContainer devmode_ctr
;
612 struct sec_desc_buf secdesc_ctr
;
613 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
615 ZERO_STRUCT(devmode_ctr
);
616 ZERO_STRUCT(secdesc_ctr
);
618 if (argc
== 1 || argc
> 3) {
619 printf("Usage: %s printername new_printername\n", argv
[0]);
624 /* Open a printer handle */
626 new_printername
= argv
[2];
629 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
631 /* get a printer handle */
632 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
636 if (!W_ERROR_IS_OK(result
))
639 /* Get printer info */
640 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
645 if (!W_ERROR_IS_OK(result
))
648 /* Modify the printername. */
649 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
650 info2
.printername
= new_printername
;
653 info_ctr
.info
.info2
= &info2
;
655 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
662 if (!NT_STATUS_IS_OK(status
)) {
663 result
= ntstatus_to_werror(status
);
666 if (W_ERROR_IS_OK(result
))
667 printf("Success in setting printername.\n");
670 if (is_valid_policy_hnd(&pol
)) {
672 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
678 /****************************************************************************
679 ****************************************************************************/
681 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
683 int argc
, const char **argv
)
685 struct policy_handle pol
;
688 const char *printername
;
689 union spoolss_PrinterInfo info
;
690 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
692 if (argc
== 1 || argc
> 3) {
693 printf("Usage: %s <printername> [level]\n", argv
[0]);
697 /* Open a printer handle */
699 level
= atoi(argv
[2]);
702 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
704 /* get a printer handle */
706 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
708 SEC_FLAG_MAXIMUM_ALLOWED
,
710 if (!W_ERROR_IS_OK(result
)) {
714 /* Get printer info */
716 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
721 if (!W_ERROR_IS_OK(result
)) {
725 /* Display printer info */
728 display_print_info0(&info
.info0
);
731 display_print_info1(&info
.info1
);
734 display_print_info2(&info
.info2
);
737 display_print_info3(&info
.info3
);
740 display_print_info4(&info
.info4
);
743 display_print_info5(&info
.info5
);
746 display_print_info6(&info
.info6
);
749 display_print_info7(&info
.info7
);
752 printf("unknown info level %d\n", level
);
756 if (is_valid_policy_hnd(&pol
)) {
758 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
764 /****************************************************************************
765 ****************************************************************************/
767 static void display_reg_value(struct regval_blob
*value
)
769 const char *text
= NULL
;
772 switch(regval_type(value
)) {
774 printf("%s: REG_DWORD: 0x%08x\n", regval_name(value
),
775 *((uint32_t *) regval_data_p(value
)));
778 blob
= data_blob_const(regval_data_p(value
), regval_size(value
));
779 pull_reg_sz(talloc_tos(), &blob
, &text
);
780 printf("%s: REG_SZ: %s\n", regval_name(value
), text
? text
: "");
783 char *hex
= hex_encode_talloc(NULL
, regval_data_p(value
), regval_size(value
));
785 printf("%s: REG_BINARY:", regval_name(value
));
787 for (i
=0; i
<len
; i
++) {
788 if (hex
[i
] == '\0') {
803 blob
= data_blob_const(regval_data_p(value
), regval_size(value
));
805 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
806 d_printf("pull_reg_multi_sz failed\n");
810 printf("%s: REG_MULTI_SZ: \n", regval_name(value
));
811 for (i
=0; values
[i
] != NULL
; i
++) {
812 d_printf("%s\n", values
[i
]);
818 printf("%s: unknown type %d\n", regval_name(value
), regval_type(value
));
823 /****************************************************************************
824 ****************************************************************************/
826 static void display_printer_data(const char *v
,
827 enum winreg_Type type
,
832 union spoolss_PrinterData r
;
833 DATA_BLOB blob
= data_blob_const(data
, length
);
836 result
= pull_spoolss_PrinterData(talloc_tos(), &blob
, &r
, type
);
837 if (!W_ERROR_IS_OK(result
)) {
843 printf("%s: REG_DWORD: 0x%08x\n", v
, r
.value
);
846 printf("%s: REG_SZ: %s\n", v
, r
.string
);
849 char *hex
= hex_encode_talloc(NULL
,
850 r
.binary
.data
, r
.binary
.length
);
852 printf("%s: REG_BINARY:", v
);
854 for (i
=0; i
<len
; i
++) {
855 if (hex
[i
] == '\0') {
868 printf("%s: REG_MULTI_SZ: ", v
);
869 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
870 printf("%s ", r
.string_array
[i
]);
875 printf("%s: unknown type 0x%02x:\n", v
, type
);
880 /****************************************************************************
881 ****************************************************************************/
883 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
885 int argc
, const char **argv
)
887 struct policy_handle pol
;
890 const char *valuename
;
891 enum winreg_Type type
;
894 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
897 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
898 printf("<printername> of . queries print server\n");
903 /* Open a printer handle */
905 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
906 fstrcpy(printername
, cli
->srv_name_slash
);
908 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
909 cli
->srv_name_slash
, argv
[1]);
911 /* get a printer handle */
913 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
915 SEC_FLAG_MAXIMUM_ALLOWED
,
917 if (!W_ERROR_IS_OK(result
))
920 /* Get printer info */
922 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
929 if (!W_ERROR_IS_OK(result
))
932 /* Display printer data */
934 display_printer_data(valuename
, type
, data
, needed
);
937 if (is_valid_policy_hnd(&pol
)) {
939 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
945 /****************************************************************************
946 ****************************************************************************/
948 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
950 int argc
, const char **argv
)
952 struct policy_handle pol
;
956 const char *valuename
, *keyname
;
958 enum winreg_Type type
;
959 uint8_t *data
= NULL
;
960 uint32_t offered
= 0;
962 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
965 printf("Usage: %s <printername> <keyname> <valuename>\n",
967 printf("<printername> of . queries print server\n");
973 /* Open a printer handle */
975 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
976 fstrcpy(printername
, cli
->srv_name_slash
);
978 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
979 cli
->srv_name_slash
, argv
[1]);
981 /* get a printer handle */
983 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
985 SEC_FLAG_MAXIMUM_ALLOWED
,
987 if (!W_ERROR_IS_OK(result
))
990 /* Get printer info */
992 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
997 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1006 if (!NT_STATUS_IS_OK(status
)) {
1007 result
= ntstatus_to_werror(status
);
1010 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
1012 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1016 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1027 if (!NT_STATUS_IS_OK(status
)) {
1028 result
= ntstatus_to_werror(status
);
1032 if (!W_ERROR_IS_OK(result
))
1035 /* Display printer data */
1037 display_printer_data(valuename
, type
, data
, needed
);
1041 if (is_valid_policy_hnd(&pol
)) {
1043 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1049 /****************************************************************************
1050 ****************************************************************************/
1052 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1058 printf("Printer Driver Info 1:\n");
1059 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1063 /****************************************************************************
1064 ****************************************************************************/
1066 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1072 printf("Printer Driver Info 2:\n");
1073 printf("\tVersion: [%x]\n", r
->version
);
1074 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1075 printf("\tArchitecture: [%s]\n", r
->architecture
);
1076 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1077 printf("\tDatafile: [%s]\n", r
->data_file
);
1078 printf("\tConfigfile: [%s]\n", r
->config_file
);
1082 /****************************************************************************
1083 ****************************************************************************/
1085 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1093 printf("Printer Driver Info 3:\n");
1094 printf("\tVersion: [%x]\n", r
->version
);
1095 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1096 printf("\tArchitecture: [%s]\n", r
->architecture
);
1097 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1098 printf("\tDatafile: [%s]\n", r
->data_file
);
1099 printf("\tConfigfile: [%s]\n", r
->config_file
);
1100 printf("\tHelpfile: [%s]\n", r
->help_file
);
1102 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1103 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1106 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1107 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1111 /****************************************************************************
1112 ****************************************************************************/
1114 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1122 printf("Printer Driver Info 4:\n");
1123 printf("\tVersion: [%x]\n", r
->version
);
1124 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1125 printf("\tArchitecture: [%s]\n", r
->architecture
);
1126 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1127 printf("\tDatafile: [%s]\n", r
->data_file
);
1128 printf("\tConfigfile: [%s]\n", r
->config_file
);
1129 printf("\tHelpfile: [%s]\n", r
->help_file
);
1131 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1132 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1135 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1136 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1138 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1139 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1144 /****************************************************************************
1145 ****************************************************************************/
1147 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1153 printf("Printer Driver Info 5:\n");
1154 printf("\tVersion: [%x]\n", r
->version
);
1155 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1156 printf("\tArchitecture: [%s]\n", r
->architecture
);
1157 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1158 printf("\tDatafile: [%s]\n", r
->data_file
);
1159 printf("\tConfigfile: [%s]\n", r
->config_file
);
1160 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1161 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1162 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1166 /****************************************************************************
1167 ****************************************************************************/
1169 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1177 printf("Printer Driver Info 6:\n");
1178 printf("\tVersion: [%x]\n", r
->version
);
1179 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1180 printf("\tArchitecture: [%s]\n", r
->architecture
);
1181 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1182 printf("\tDatafile: [%s]\n", r
->data_file
);
1183 printf("\tConfigfile: [%s]\n", r
->config_file
);
1184 printf("\tHelpfile: [%s]\n", r
->help_file
);
1186 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1187 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1190 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1191 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1193 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1194 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1197 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1198 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1199 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1200 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1201 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1202 printf("\tProvider: [%s]\n", r
->provider
);
1207 /****************************************************************************
1208 ****************************************************************************/
1210 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1218 printf("Printer Driver Info 8:\n");
1219 printf("\tVersion: [%x]\n", r
->version
);
1220 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1221 printf("\tArchitecture: [%s]\n", r
->architecture
);
1222 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1223 printf("\tDatafile: [%s]\n", r
->data_file
);
1224 printf("\tConfigfile: [%s]\n", r
->config_file
);
1225 printf("\tHelpfile: [%s]\n", r
->help_file
);
1226 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1227 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1229 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1230 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1233 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1234 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1237 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1238 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1239 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1240 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1241 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1242 printf("\tProvider: [%s]\n", r
->provider
);
1243 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1244 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1245 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1246 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1248 printf("\tInf Path: [%s]\n", r
->inf_path
);
1249 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1250 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1251 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1253 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1254 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1255 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1260 /****************************************************************************
1261 ****************************************************************************/
1263 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1264 TALLOC_CTX
*mem_ctx
,
1265 int argc
, const char **argv
)
1267 struct policy_handle pol
;
1270 const char *printername
;
1272 bool success
= false;
1273 union spoolss_DriverInfo info
;
1274 uint32_t server_major_version
;
1275 uint32_t server_minor_version
;
1276 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1278 if ((argc
== 1) || (argc
> 3)) {
1279 printf("Usage: %s <printername> [level]\n", argv
[0]);
1283 /* get the arguments need to open the printer handle */
1285 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1288 level
= atoi(argv
[2]);
1291 /* Open a printer handle */
1293 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1297 if (!W_ERROR_IS_OK(werror
)) {
1298 printf("Error opening printer handle for %s!\n", printername
);
1302 /* loop through and print driver info level for each architecture */
1304 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1306 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1308 archi_table
[i
].long_archi
,
1311 archi_table
[i
].version
,
1314 &server_major_version
,
1315 &server_minor_version
);
1316 if (!W_ERROR_IS_OK(werror
)) {
1320 /* need at least one success */
1324 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1328 display_print_driver1(&info
.info1
);
1331 display_print_driver2(&info
.info2
);
1334 display_print_driver3(&info
.info3
);
1337 display_print_driver4(&info
.info4
);
1340 display_print_driver5(&info
.info5
);
1343 display_print_driver6(&info
.info6
);
1346 display_print_driver8(&info
.info8
);
1349 printf("unknown info level %d\n", level
);
1356 if (is_valid_policy_hnd(&pol
)) {
1358 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1368 /****************************************************************************
1369 ****************************************************************************/
1371 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1372 TALLOC_CTX
*mem_ctx
,
1373 const char *architecture
,
1378 union spoolss_DriverInfo
*info
= NULL
;
1381 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1382 cli
->srv_name_slash
,
1389 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1390 printf("Server does not support environment [%s]\n",
1399 if (!W_ERROR_IS_OK(werror
)) {
1400 printf("Error getting driver for environment [%s] - %s\n",
1401 architecture
, win_errstr(werror
));
1405 printf("\n[%s]\n", architecture
);
1409 for (j
=0; j
< count
; j
++) {
1410 display_print_driver1(&info
[j
].info1
);
1414 for (j
=0; j
< count
; j
++) {
1415 display_print_driver2(&info
[j
].info2
);
1419 for (j
=0; j
< count
; j
++) {
1420 display_print_driver3(&info
[j
].info3
);
1424 for (j
=0; j
< count
; j
++) {
1425 display_print_driver4(&info
[j
].info4
);
1429 for (j
=0; j
< count
; j
++) {
1430 display_print_driver5(&info
[j
].info5
);
1434 for (j
=0; j
< count
; j
++) {
1435 display_print_driver6(&info
[j
].info6
);
1439 for (j
=0; j
< count
; j
++) {
1440 display_print_driver8(&info
[j
].info8
);
1444 printf("unknown info level %d\n", level
);
1445 return WERR_UNKNOWN_LEVEL
;
1451 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1452 TALLOC_CTX
*mem_ctx
,
1453 int argc
, const char **argv
)
1455 WERROR werror
= WERR_OK
;
1458 const char *architecture
= NULL
;
1461 printf("Usage: enumdrivers [level] [architecture]\n");
1466 level
= atoi(argv
[1]);
1470 architecture
= argv
[2];
1474 return enum_driver_by_architecture(cli
, mem_ctx
,
1479 /* loop through and print driver info level for each architecture */
1480 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1481 /* check to see if we already asked for this architecture string */
1483 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1487 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1488 archi_table
[i
].long_archi
,
1490 if (!W_ERROR_IS_OK(werror
)) {
1498 /****************************************************************************
1499 ****************************************************************************/
1501 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1503 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1506 /****************************************************************************
1507 ****************************************************************************/
1509 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1510 TALLOC_CTX
*mem_ctx
,
1511 int argc
, const char **argv
)
1515 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1518 union spoolss_DriverDirectoryInfo info
;
1520 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1523 printf("Usage: %s [environment]\n", argv
[0]);
1527 /* Get the arguments need to open the printer handle */
1533 /* Get the directory. Only use Info level 1 */
1535 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1536 cli
->srv_name_slash
,
1544 if (!NT_STATUS_IS_OK(status
)) {
1545 return ntstatus_to_werror(status
);
1547 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1549 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1551 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1552 cli
->srv_name_slash
,
1560 if (!NT_STATUS_IS_OK(status
)) {
1561 return ntstatus_to_werror(status
);
1565 if (W_ERROR_IS_OK(result
)) {
1566 display_printdriverdir_1(&info
.info1
);
1572 /****************************************************************************
1573 ****************************************************************************/
1575 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1576 struct spoolss_AddDriverInfo3
*info
,
1582 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1584 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1586 info
->version
= archi_table
[i
].version
;
1587 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1592 if (archi_table
[i
].long_archi
== NULL
)
1594 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1601 /**************************************************************************
1602 wrapper for strtok to get the next parameter from a delimited list.
1603 Needed to handle the empty parameter string denoted by "NULL"
1604 *************************************************************************/
1606 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1607 const char *delim
, const char **dest
,
1612 /* get the next token */
1613 ptr
= strtok_r(str
, delim
, saveptr
);
1615 /* a string of 'NULL' is used to represent an empty
1616 parameter because two consecutive delimiters
1617 will not return an empty string. See man strtok(3)
1619 if (ptr
&& (strcasecmp_m(ptr
, "NULL") == 0)) {
1624 *dest
= talloc_strdup(mem_ctx
, ptr
);
1630 /********************************************************************************
1631 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1632 string in the form of
1633 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1634 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1635 <Default Data Type>:<Comma Separated list of Files>
1636 *******************************************************************************/
1638 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1643 char *saveptr
= NULL
;
1644 struct spoolss_StringArray
*deps
;
1645 const char **file_array
= NULL
;
1648 /* fill in the UNISTR fields */
1649 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1650 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1651 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1652 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1653 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1654 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1655 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1657 /* <Comma Separated List of Dependent Files> */
1658 /* save the beginning of the string */
1659 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1662 /* begin to strip out each filename */
1663 str
= strtok_r(str
, ",", &saveptr
);
1665 /* no dependent files, we are done */
1670 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1675 while (str
!= NULL
) {
1676 add_string_to_array(deps
, str
, &file_array
, &count
);
1677 str
= strtok_r(NULL
, ",", &saveptr
);
1680 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1681 if (!deps
->string
) {
1685 for (i
=0; i
< count
; i
++) {
1686 deps
->string
[i
] = file_array
[i
];
1689 r
->dependent_files
= deps
;
1694 /****************************************************************************
1695 ****************************************************************************/
1697 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1698 TALLOC_CTX
*mem_ctx
,
1699 int argc
, const char **argv
)
1704 struct spoolss_AddDriverInfoCtr info_ctr
;
1705 struct spoolss_AddDriverInfo3 info3
;
1708 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1710 /* parse the command arguments */
1711 if (argc
!= 3 && argc
!= 4)
1713 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1714 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1715 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1716 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1717 printf ("\t[version]\n");
1722 /* Fill in the spoolss_AddDriverInfo3 struct */
1725 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1727 printf ("Error Unknown architecture [%s]\n", argv
[1]);
1728 return WERR_INVALID_PARAM
;
1731 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1733 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1734 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1736 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1737 return WERR_INVALID_PARAM
;
1740 /* if printer driver version specified, override the default version
1741 * used by the architecture. This allows installation of Windows
1742 * 2000 (version 3) printer drivers. */
1745 info3
.version
= atoi(argv
[3]);
1749 info_ctr
.level
= level
;
1750 info_ctr
.info
.info3
= &info3
;
1752 status
= dcerpc_spoolss_AddPrinterDriver(b
, mem_ctx
,
1753 cli
->srv_name_slash
,
1756 if (!NT_STATUS_IS_OK(status
)) {
1757 return ntstatus_to_werror(status
);
1759 if (W_ERROR_IS_OK(result
)) {
1760 printf ("Printer Driver %s successfully installed.\n",
1768 /****************************************************************************
1769 ****************************************************************************/
1771 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1772 TALLOC_CTX
*mem_ctx
,
1773 int argc
, const char **argv
)
1776 struct spoolss_SetPrinterInfoCtr info_ctr
;
1777 struct spoolss_SetPrinterInfo2 info2
;
1779 /* parse the command arguments */
1782 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1786 /* Fill in the DRIVER_INFO_2 struct */
1789 info2
.printername
= argv
[1];
1790 info2
.drivername
= argv
[3];
1791 info2
.sharename
= argv
[2];
1792 info2
.portname
= argv
[4];
1793 info2
.comment
= "Created by rpcclient";
1794 info2
.printprocessor
= "winprint";
1795 info2
.datatype
= "RAW";
1796 info2
.devmode_ptr
= 0;
1797 info2
.secdesc_ptr
= 0;
1798 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1800 info2
.defaultpriority
= 0;
1801 info2
.starttime
= 0;
1802 info2
.untiltime
= 0;
1804 /* These three fields must not be used by AddPrinter()
1805 as defined in the MS Platform SDK documentation..
1809 info2.averageppm = 0;
1813 info_ctr
.info
.info2
= &info2
;
1815 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1817 if (W_ERROR_IS_OK(result
))
1818 printf ("Printer %s successfully installed.\n", argv
[1]);
1823 /****************************************************************************
1824 ****************************************************************************/
1826 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1827 TALLOC_CTX
*mem_ctx
,
1828 int argc
, const char **argv
)
1830 struct policy_handle pol
;
1834 const char *printername
;
1835 union spoolss_PrinterInfo info
;
1836 struct spoolss_SetPrinterInfoCtr info_ctr
;
1837 struct spoolss_SetPrinterInfo2 info2
;
1838 struct spoolss_DevmodeContainer devmode_ctr
;
1839 struct sec_desc_buf secdesc_ctr
;
1840 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1842 ZERO_STRUCT(devmode_ctr
);
1843 ZERO_STRUCT(secdesc_ctr
);
1845 /* parse the command arguments */
1848 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1852 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1854 /* Get a printer handle */
1856 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1860 if (!W_ERROR_IS_OK(result
))
1863 /* Get printer info */
1865 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1870 if (!W_ERROR_IS_OK(result
)) {
1871 printf ("Unable to retrieve printer information!\n");
1875 /* Set the printer driver */
1877 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
1878 info2
.drivername
= argv
[2];
1881 info_ctr
.info
.info2
= &info2
;
1883 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
1890 if (!NT_STATUS_IS_OK(status
)) {
1891 result
= ntstatus_to_werror(status
);
1894 if (!W_ERROR_IS_OK(result
)) {
1895 printf("SetPrinter call failed!\n");
1899 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1904 if (is_valid_policy_hnd(&pol
)) {
1906 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1913 /****************************************************************************
1914 ****************************************************************************/
1916 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1917 TALLOC_CTX
*mem_ctx
,
1918 int argc
, const char **argv
)
1920 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1922 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1927 const char *arch
= NULL
;
1928 uint32_t delete_flags
= 0;
1930 /* parse the command arguments */
1931 if (argc
< 2 || argc
> 4) {
1932 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1939 vers
= atoi (argv
[3]);
1942 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1945 /* delete the driver for all architectures */
1946 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1948 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1951 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1954 /* make the call to remove the driver */
1955 status
= dcerpc_spoolss_DeletePrinterDriverEx(b
, mem_ctx
,
1956 cli
->srv_name_slash
,
1957 archi_table
[i
].long_archi
,
1960 archi_table
[i
].version
,
1962 if (!NT_STATUS_IS_OK(status
)) {
1963 return ntstatus_to_werror(status
);
1965 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] (version: %d): %s\n",
1969 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1974 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1975 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1984 /****************************************************************************
1985 ****************************************************************************/
1987 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1988 TALLOC_CTX
*mem_ctx
,
1989 int argc
, const char **argv
)
1991 WERROR result
= WERR_OK
;
1994 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1996 /* parse the command arguments */
1998 printf ("Usage: %s <driver>\n", argv
[0]);
2002 /* delete the driver for all architectures */
2003 for (i
=0; archi_table
[i
].long_archi
; i
++) {
2006 /* make the call to remove the driver */
2007 status
= dcerpc_spoolss_DeletePrinterDriver(b
, mem_ctx
,
2008 cli
->srv_name_slash
,
2009 archi_table
[i
].long_archi
,
2012 if (!NT_STATUS_IS_OK(status
)) {
2013 result
= ntstatus_to_werror(status
);
2016 if ( !W_ERROR_IS_OK(result
) ) {
2017 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
2018 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
2019 argv
[1], archi_table
[i
].long_archi
,
2020 win_errstr(result
));
2023 printf ("Driver %s removed for arch [%s].\n", argv
[1],
2024 archi_table
[i
].long_archi
);
2031 /****************************************************************************
2032 ****************************************************************************/
2034 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
2035 TALLOC_CTX
*mem_ctx
,
2036 int argc
, const char **argv
)
2040 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
2043 union spoolss_PrintProcessorDirectoryInfo info
;
2045 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2047 /* parse the command arguments */
2049 printf ("Usage: %s [environment]\n", argv
[0]);
2054 environment
= argv
[1];
2057 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2058 cli
->srv_name_slash
,
2066 if (!NT_STATUS_IS_OK(status
)) {
2067 return ntstatus_to_werror(status
);
2069 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2071 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2073 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2074 cli
->srv_name_slash
,
2082 if (!NT_STATUS_IS_OK(status
)) {
2083 return ntstatus_to_werror(status
);
2087 if (W_ERROR_IS_OK(result
)) {
2088 printf("%s\n", info
.info1
.directory_name
);
2094 /****************************************************************************
2095 ****************************************************************************/
2097 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2098 int argc
, const char **argv
)
2100 struct policy_handle handle
;
2103 const char *printername
;
2104 union spoolss_AddFormInfo info
;
2105 struct spoolss_AddFormInfo1 info1
;
2106 struct spoolss_AddFormInfo2 info2
;
2108 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2110 /* Parse the command arguments */
2112 if (argc
< 3 || argc
> 5) {
2113 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2117 /* Get a printer handle */
2119 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2121 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2125 if (!W_ERROR_IS_OK(werror
))
2128 /* Dummy up some values for the form data */
2131 level
= atoi(argv
[3]);
2136 info1
.flags
= SPOOLSS_FORM_USER
;
2137 info1
.form_name
= argv
[2];
2138 info1
.size
.width
= 100;
2139 info1
.size
.height
= 100;
2140 info1
.area
.left
= 0;
2141 info1
.area
.top
= 10;
2142 info1
.area
.right
= 20;
2143 info1
.area
.bottom
= 30;
2145 info
.info1
= &info1
;
2149 info2
.flags
= SPOOLSS_FORM_USER
;
2150 info2
.form_name
= argv
[2];
2151 info2
.size
.width
= 100;
2152 info2
.size
.height
= 100;
2153 info2
.area
.left
= 0;
2154 info2
.area
.top
= 10;
2155 info2
.area
.right
= 20;
2156 info2
.area
.bottom
= 30;
2157 info2
.keyword
= argv
[2];
2158 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2159 info2
.mui_dll
= NULL
;
2160 info2
.ressource_id
= 0;
2161 info2
.display_name
= argv
[2];
2164 info
.info2
= &info2
;
2168 werror
= WERR_INVALID_PARAM
;
2175 status
= dcerpc_spoolss_AddForm(b
, mem_ctx
,
2180 if (!NT_STATUS_IS_OK(status
)) {
2181 werror
= ntstatus_to_werror(status
);
2185 if (is_valid_policy_hnd(&handle
)) {
2187 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2193 /****************************************************************************
2194 ****************************************************************************/
2196 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2197 int argc
, const char **argv
)
2199 struct policy_handle handle
;
2202 const char *printername
;
2203 union spoolss_AddFormInfo info
;
2204 struct spoolss_AddFormInfo1 info1
;
2205 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2207 /* Parse the command arguments */
2210 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2214 /* Get a printer handle */
2216 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2218 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2220 SEC_FLAG_MAXIMUM_ALLOWED
,
2222 if (!W_ERROR_IS_OK(werror
))
2225 /* Dummy up some values for the form data */
2227 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2228 info1
.size
.width
= 100;
2229 info1
.size
.height
= 100;
2230 info1
.area
.left
= 0;
2231 info1
.area
.top
= 1000;
2232 info1
.area
.right
= 2000;
2233 info1
.area
.bottom
= 3000;
2234 info1
.form_name
= argv
[2];
2236 info
.info1
= &info1
;
2240 status
= dcerpc_spoolss_SetForm(b
, mem_ctx
,
2246 if (!NT_STATUS_IS_OK(status
)) {
2247 werror
= ntstatus_to_werror(status
);
2251 if (is_valid_policy_hnd(&handle
)) {
2253 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2259 /****************************************************************************
2260 ****************************************************************************/
2262 static const char *get_form_flag(int form_flag
)
2264 switch (form_flag
) {
2265 case SPOOLSS_FORM_USER
:
2267 case SPOOLSS_FORM_BUILTIN
:
2268 return "FORM_BUILTIN";
2269 case SPOOLSS_FORM_PRINTER
:
2270 return "FORM_PRINTER";
2276 /****************************************************************************
2277 ****************************************************************************/
2279 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2282 "\tflag: %s (%d)\n" \
2283 "\twidth: %d, length: %d\n" \
2284 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2285 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2286 r
->size
.width
, r
->size
.height
,
2287 r
->area
.left
, r
->area
.right
,
2288 r
->area
.top
, r
->area
.bottom
);
2291 /****************************************************************************
2292 ****************************************************************************/
2294 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2297 "\tflag: %s (%d)\n" \
2298 "\twidth: %d, length: %d\n" \
2299 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2300 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2301 r
->size
.width
, r
->size
.height
,
2302 r
->area
.left
, r
->area
.right
,
2303 r
->area
.top
, r
->area
.bottom
);
2304 printf("\tkeyword: %s\n", r
->keyword
);
2305 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2306 printf("\tmui_dll: %s\n", r
->mui_dll
);
2307 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2308 printf("\tdisplay_name: %s\n", r
->display_name
);
2309 printf("\tlang_id: %d\n", r
->lang_id
);
2313 /****************************************************************************
2314 ****************************************************************************/
2316 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2317 int argc
, const char **argv
)
2319 struct policy_handle handle
;
2322 const char *printername
;
2324 uint32_t offered
= 0;
2325 union spoolss_FormInfo info
;
2328 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2330 /* Parse the command arguments */
2332 if (argc
< 3 || argc
> 5) {
2333 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2337 /* Get a printer handle */
2339 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2341 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2343 SEC_FLAG_MAXIMUM_ALLOWED
,
2345 if (!W_ERROR_IS_OK(werror
))
2349 level
= atoi(argv
[3]);
2354 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2363 if (!NT_STATUS_IS_OK(status
)) {
2364 werror
= ntstatus_to_werror(status
);
2367 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2368 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2370 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2379 if (!NT_STATUS_IS_OK(status
)) {
2380 werror
= ntstatus_to_werror(status
);
2385 if (!W_ERROR_IS_OK(werror
)) {
2391 display_form_info1(&info
.info1
);
2394 display_form_info2(&info
.info2
);
2399 if (is_valid_policy_hnd(&handle
)) {
2401 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2407 /****************************************************************************
2408 ****************************************************************************/
2410 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2411 TALLOC_CTX
*mem_ctx
, int argc
,
2414 struct policy_handle handle
;
2417 const char *printername
;
2418 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2420 /* Parse the command arguments */
2423 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2427 /* Get a printer handle */
2429 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2431 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2433 SEC_FLAG_MAXIMUM_ALLOWED
,
2435 if (!W_ERROR_IS_OK(werror
))
2438 /* Delete the form */
2440 status
= dcerpc_spoolss_DeleteForm(b
, mem_ctx
,
2444 if (!NT_STATUS_IS_OK(status
)) {
2445 werror
= ntstatus_to_werror(status
);
2450 if (is_valid_policy_hnd(&handle
)) {
2452 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2458 /****************************************************************************
2459 ****************************************************************************/
2461 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2462 TALLOC_CTX
*mem_ctx
, int argc
,
2465 struct policy_handle handle
;
2467 const char *printername
;
2468 uint32_t num_forms
, level
= 1, i
;
2469 union spoolss_FormInfo
*forms
;
2470 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2472 /* Parse the command arguments */
2474 if (argc
< 2 || argc
> 4) {
2475 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2479 /* Get a printer handle */
2481 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2483 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2485 SEC_FLAG_MAXIMUM_ALLOWED
,
2487 if (!W_ERROR_IS_OK(werror
))
2491 level
= atoi(argv
[2]);
2494 /* Enumerate forms */
2496 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2503 if (!W_ERROR_IS_OK(werror
))
2506 /* Display output */
2508 for (i
= 0; i
< num_forms
; i
++) {
2511 display_form_info1(&forms
[i
].info1
);
2514 display_form_info2(&forms
[i
].info2
);
2520 if (is_valid_policy_hnd(&handle
)) {
2522 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2528 /****************************************************************************
2529 ****************************************************************************/
2531 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2532 TALLOC_CTX
*mem_ctx
,
2533 int argc
, const char **argv
)
2537 const char *printername
;
2538 struct policy_handle pol
;
2539 union spoolss_PrinterInfo info
;
2540 enum winreg_Type type
;
2541 union spoolss_PrinterData data
;
2543 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2545 /* parse the command arguments */
2547 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2548 " <value> <data>\n",
2553 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2557 if (strequal(argv
[2], "string")) {
2561 if (strequal(argv
[2], "binary")) {
2565 if (strequal(argv
[2], "dword")) {
2569 if (strequal(argv
[2], "multistring")) {
2570 type
= REG_MULTI_SZ
;
2573 if (type
== REG_NONE
) {
2574 printf("Unknown data type: %s\n", argv
[2]);
2575 result
= WERR_INVALID_PARAM
;
2579 /* get a printer handle */
2581 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2583 SEC_FLAG_MAXIMUM_ALLOWED
,
2585 if (!W_ERROR_IS_OK(result
)) {
2589 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2594 if (!W_ERROR_IS_OK(result
)) {
2598 printf("%s\n", current_timestring(mem_ctx
, true));
2599 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2601 /* Set the printer data */
2605 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2606 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2609 data
.value
= strtoul(argv
[4], NULL
, 10);
2612 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2614 case REG_MULTI_SZ
: {
2616 const char **strings
= NULL
;
2618 for (i
=4; i
<argc
; i
++) {
2619 if (strcmp(argv
[i
], "NULL") == 0) {
2622 if (!add_string_to_array(mem_ctx
, argv
[i
],
2625 result
= WERR_NOMEM
;
2629 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2630 if (!data
.string_array
) {
2631 result
= WERR_NOMEM
;
2634 for (i
=0; i
< num_strings
; i
++) {
2635 data
.string_array
[i
] = strings
[i
];
2640 printf("Unknown data type: %s\n", argv
[2]);
2641 result
= WERR_INVALID_PARAM
;
2645 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2646 if (!W_ERROR_IS_OK(result
)) {
2650 status
= dcerpc_spoolss_SetPrinterData(b
, mem_ctx
,
2652 argv
[3], /* value_name */
2657 if (!NT_STATUS_IS_OK(status
)) {
2658 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2659 result
= ntstatus_to_werror(status
);
2662 if (!W_ERROR_IS_OK(result
)) {
2663 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2666 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2668 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2673 if (!W_ERROR_IS_OK(result
)) {
2677 printf("%s\n", current_timestring(mem_ctx
, true));
2678 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2682 if (is_valid_policy_hnd(&pol
)) {
2684 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
2690 /****************************************************************************
2691 ****************************************************************************/
2693 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2695 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2696 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2700 /****************************************************************************
2701 ****************************************************************************/
2703 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2705 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2706 r
->position
, r
->job_id
,
2707 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2708 r
->total_pages
, r
->size
);
2711 /****************************************************************************
2712 ****************************************************************************/
2714 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2716 printf("jobid[%d], next_jobid[%d]\n",
2717 r
->job_id
, r
->next_job_id
);
2720 /****************************************************************************
2721 ****************************************************************************/
2723 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2725 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2726 r
->position
, r
->job_id
,
2727 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2728 r
->total_pages
, r
->size
, r
->size_high
);
2731 /****************************************************************************
2732 ****************************************************************************/
2734 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2735 TALLOC_CTX
*mem_ctx
, int argc
,
2739 uint32_t level
= 1, count
, i
;
2740 const char *printername
;
2741 struct policy_handle hnd
;
2742 union spoolss_JobInfo
*info
;
2743 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2745 if (argc
< 2 || argc
> 3) {
2746 printf("Usage: %s printername [level]\n", argv
[0]);
2751 level
= atoi(argv
[2]);
2754 /* Open printer handle */
2756 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2758 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2760 SEC_FLAG_MAXIMUM_ALLOWED
,
2762 if (!W_ERROR_IS_OK(result
))
2765 /* Enumerate ports */
2767 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2775 if (!W_ERROR_IS_OK(result
)) {
2779 for (i
= 0; i
< count
; i
++) {
2782 display_job_info1(&info
[i
].info1
);
2785 display_job_info2(&info
[i
].info2
);
2788 d_printf("unknown info level %d\n", level
);
2794 if (is_valid_policy_hnd(&hnd
)) {
2796 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2802 /****************************************************************************
2803 ****************************************************************************/
2805 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2806 TALLOC_CTX
*mem_ctx
, int argc
,
2810 const char *printername
;
2811 struct policy_handle hnd
;
2814 union spoolss_JobInfo info
;
2815 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2817 if (argc
< 3 || argc
> 4) {
2818 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2822 job_id
= atoi(argv
[2]);
2825 level
= atoi(argv
[3]);
2828 /* Open printer handle */
2830 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2832 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2834 SEC_FLAG_MAXIMUM_ALLOWED
,
2836 if (!W_ERROR_IS_OK(result
)) {
2840 /* Enumerate ports */
2842 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2849 if (!W_ERROR_IS_OK(result
)) {
2855 display_job_info1(&info
.info1
);
2858 display_job_info2(&info
.info2
);
2861 display_job_info3(&info
.info3
);
2864 display_job_info4(&info
.info4
);
2867 d_printf("unknown info level %d\n", level
);
2872 if (is_valid_policy_hnd(&hnd
)) {
2874 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2880 /****************************************************************************
2881 ****************************************************************************/
2885 enum spoolss_JobControl val
;
2887 {"PAUSE", SPOOLSS_JOB_CONTROL_PAUSE
},
2888 {"RESUME", SPOOLSS_JOB_CONTROL_RESUME
},
2889 {"CANCEL", SPOOLSS_JOB_CONTROL_CANCEL
},
2890 {"RESTART", SPOOLSS_JOB_CONTROL_RESTART
},
2891 {"DELETE", SPOOLSS_JOB_CONTROL_DELETE
},
2892 {"SEND_TO_PRINTER", SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER
},
2893 {"EJECTED", SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED
},
2894 {"RETAIN", SPOOLSS_JOB_CONTROL_RETAIN
},
2895 {"RELEASE", SPOOLSS_JOB_CONTROL_RELEASE
}
2898 static enum spoolss_JobControl
parse_setjob_command(const char *cmd
)
2902 for (i
= 0; i
< sizeof(cmdvals
)/sizeof(cmdvals
[0]); i
++) {
2903 if (strequal(cmdvals
[i
].name
, cmd
)) {
2904 return cmdvals
[i
].val
;
2907 return (enum spoolss_JobControl
)atoi(cmd
);
2910 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2911 TALLOC_CTX
*mem_ctx
, int argc
,
2916 const char *printername
;
2917 struct policy_handle hnd
;
2919 enum spoolss_JobControl command
;
2920 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2923 printf("Usage: %s printername job_id command\n", argv
[0]);
2924 printf("command = [PAUSE|RESUME|CANCEL|RESTART|DELETE|"
2925 "SEND_TO_PRINTER|EJECTED|RETAIN|RELEASE]\n");
2929 job_id
= atoi(argv
[2]);
2930 command
= parse_setjob_command(argv
[3]);
2932 /* Open printer handle */
2934 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2936 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2938 SEC_FLAG_MAXIMUM_ALLOWED
,
2940 if (!W_ERROR_IS_OK(result
)) {
2946 status
= dcerpc_spoolss_SetJob(b
, mem_ctx
,
2952 if (!NT_STATUS_IS_OK(status
)) {
2953 result
= ntstatus_to_werror(status
);
2956 if (!W_ERROR_IS_OK(result
)) {
2961 if (is_valid_policy_hnd(&hnd
)) {
2963 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2969 /****************************************************************************
2970 ****************************************************************************/
2972 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2973 TALLOC_CTX
*mem_ctx
, int argc
,
2978 const char *printername
;
2979 struct policy_handle hnd
;
2980 uint32_t value_needed
;
2981 enum winreg_Type type
;
2982 uint32_t data_needed
;
2983 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2984 struct spoolss_EnumPrinterData r
;
2987 printf("Usage: %s printername\n", argv
[0]);
2991 /* Open printer handle */
2993 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2995 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2997 SEC_FLAG_MAXIMUM_ALLOWED
,
2999 if (!W_ERROR_IS_OK(result
)) {
3003 /* Enumerate data */
3006 r
.in
.enum_index
= 0;
3007 r
.in
.value_offered
= 0;
3008 r
.in
.data_offered
= 0;
3009 r
.out
.value_name
= NULL
;
3010 r
.out
.value_needed
= &value_needed
;
3013 r
.out
.data_needed
= &data_needed
;
3015 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3016 if (!NT_STATUS_IS_OK(status
)) {
3017 result
= ntstatus_to_werror(status
);
3021 if (!W_ERROR_IS_OK(r
.out
.result
)) {
3022 result
= r
.out
.result
;
3026 r
.in
.data_offered
= *r
.out
.data_needed
;
3027 r
.in
.value_offered
= *r
.out
.value_needed
;
3028 r
.out
.data
= talloc_zero_array(mem_ctx
, uint8_t, r
.in
.data_offered
);
3029 r
.out
.value_name
= talloc_zero_array(mem_ctx
, char, r
.in
.value_offered
);
3033 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3034 if (!NT_STATUS_IS_OK(status
)) {
3035 result
= ntstatus_to_werror(status
);
3039 if (W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
3047 struct regval_blob
*v
;
3049 v
= regval_compose(talloc_tos(),
3055 result
= WERR_NOMEM
;
3059 display_reg_value(v
);
3063 } while (W_ERROR_IS_OK(r
.out
.result
));
3066 if (is_valid_policy_hnd(&hnd
)) {
3068 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3074 /****************************************************************************
3075 ****************************************************************************/
3077 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
3078 TALLOC_CTX
*mem_ctx
, int argc
,
3083 const char *printername
;
3084 struct policy_handle hnd
;
3086 struct spoolss_PrinterEnumValues
*info
;
3087 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3090 printf("Usage: %s printername <keyname>\n", argv
[0]);
3094 /* Open printer handle */
3096 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3098 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3100 SEC_FLAG_MAXIMUM_ALLOWED
,
3102 if (!W_ERROR_IS_OK(result
)) {
3106 /* Enumerate subkeys */
3108 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
3114 if (!W_ERROR_IS_OK(result
)) {
3118 for (i
=0; i
< count
; i
++) {
3119 display_printer_data(info
[i
].value_name
,
3122 info
[i
].data
->length
);
3126 if (is_valid_policy_hnd(&hnd
)) {
3128 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3134 /****************************************************************************
3135 ****************************************************************************/
3137 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
3138 TALLOC_CTX
*mem_ctx
, int argc
,
3142 const char *printername
;
3143 const char *keyname
= NULL
;
3144 struct policy_handle hnd
;
3145 const char **key_buffer
= NULL
;
3147 uint32_t offered
= 0;
3148 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3150 if (argc
< 2 || argc
> 4) {
3151 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3162 offered
= atoi(argv
[3]);
3165 /* Open printer handle */
3167 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3169 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3171 SEC_FLAG_MAXIMUM_ALLOWED
,
3173 if (!W_ERROR_IS_OK(result
)) {
3177 /* Enumerate subkeys */
3179 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3185 if (!W_ERROR_IS_OK(result
)) {
3189 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3190 printf("%s\n", key_buffer
[i
]);
3195 if (is_valid_policy_hnd(&hnd
)) {
3197 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3203 /****************************************************************************
3204 ****************************************************************************/
3206 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3207 TALLOC_CTX
*mem_ctx
, int argc
,
3210 const char *printername
;
3211 const char *clientname
;
3212 struct policy_handle hnd
;
3215 struct spoolss_NotifyOption option
;
3216 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3219 printf("Usage: %s printername\n", argv
[0]);
3226 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3228 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3230 SEC_FLAG_MAXIMUM_ALLOWED
,
3232 if (!W_ERROR_IS_OK(result
)) {
3233 printf("Error opening %s\n", argv
[1]);
3237 /* Create spool options */
3242 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3243 if (option
.types
== NULL
) {
3244 result
= WERR_NOMEM
;
3248 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3249 option
.types
[0].count
= 1;
3250 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3251 if (option
.types
[0].fields
== NULL
) {
3252 result
= WERR_NOMEM
;
3255 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3257 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3258 option
.types
[1].count
= 1;
3259 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3260 if (option
.types
[1].fields
== NULL
) {
3261 result
= WERR_NOMEM
;
3264 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3266 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", lp_netbios_name());
3268 result
= WERR_NOMEM
;
3274 status
= dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(b
, mem_ctx
,
3282 if (!NT_STATUS_IS_OK(status
)) {
3283 result
= ntstatus_to_werror(status
);
3286 if (!W_ERROR_IS_OK(result
)) {
3287 printf("Error rffpcnex %s\n", argv
[1]);
3292 if (is_valid_policy_hnd(&hnd
)) {
3294 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3300 /****************************************************************************
3301 ****************************************************************************/
3303 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3304 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3306 union spoolss_PrinterInfo info1
, info2
;
3308 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3310 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3311 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3316 if ( !W_ERROR_IS_OK(werror
) ) {
3317 printf("failed (%s)\n", win_errstr(werror
));
3318 talloc_destroy(mem_ctx
);
3323 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3324 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3329 if ( !W_ERROR_IS_OK(werror
) ) {
3330 printf("failed (%s)\n", win_errstr(werror
));
3331 talloc_destroy(mem_ctx
);
3336 talloc_destroy(mem_ctx
);
3341 /****************************************************************************
3342 ****************************************************************************/
3344 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3345 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3347 union spoolss_PrinterInfo info1
, info2
;
3349 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3350 struct security_descriptor
*sd1
, *sd2
;
3354 printf("Retrieving printer security for %s...", cli1
->desthost
);
3355 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3360 if ( !W_ERROR_IS_OK(werror
) ) {
3361 printf("failed (%s)\n", win_errstr(werror
));
3367 printf("Retrieving printer security for %s...", cli2
->desthost
);
3368 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3373 if ( !W_ERROR_IS_OK(werror
) ) {
3374 printf("failed (%s)\n", win_errstr(werror
));
3383 sd1
= info1
.info3
.secdesc
;
3384 sd2
= info2
.info3
.secdesc
;
3386 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3387 printf("NULL secdesc!\n");
3392 if (!security_descriptor_equal( sd1
, sd2
) ) {
3393 printf("Security Descriptors *not* equal!\n");
3398 printf("Security descriptors match\n");
3401 talloc_destroy(mem_ctx
);
3406 /****************************************************************************
3407 ****************************************************************************/
3409 extern struct user_auth_info
*rpcclient_auth_info
;
3411 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3412 TALLOC_CTX
*mem_ctx
, int argc
,
3415 const char *printername
;
3416 char *printername_path
= NULL
;
3417 struct cli_state
*cli_server2
= NULL
;
3418 struct rpc_pipe_client
*cli2
= NULL
;
3419 struct policy_handle hPrinter1
, hPrinter2
;
3424 printf("Usage: %s <printer> <server>\n", argv
[0]);
3428 printername
= argv
[1];
3430 /* first get the connection to the remote server */
3432 nt_status
= cli_full_connection(&cli_server2
, lp_netbios_name(), argv
[2],
3435 get_cmdline_auth_info_username(rpcclient_auth_info
),
3437 get_cmdline_auth_info_password(rpcclient_auth_info
),
3438 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3439 get_cmdline_auth_info_signing_state(rpcclient_auth_info
));
3441 if ( !NT_STATUS_IS_OK(nt_status
) )
3442 return WERR_GENERAL_FAILURE
;
3444 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
.syntax_id
,
3446 if (!NT_STATUS_IS_OK(nt_status
)) {
3447 printf("failed to open spoolss pipe on server %s (%s)\n",
3448 argv
[2], nt_errstr(nt_status
));
3449 return WERR_GENERAL_FAILURE
;
3452 /* now open up both printers */
3454 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3456 printf("Opening %s...", printername_path
);
3458 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3462 if ( !W_ERROR_IS_OK(werror
) ) {
3463 printf("failed (%s)\n", win_errstr(werror
));
3468 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3470 printf("Opening %s...", printername_path
);
3471 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3475 if ( !W_ERROR_IS_OK(werror
) ) {
3476 printf("failed (%s)\n", win_errstr(werror
));
3481 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3482 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3484 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3491 printf("Closing printers...");
3494 dcerpc_spoolss_ClosePrinter(cli
->binding_handle
, mem_ctx
, &hPrinter1
, &_result
);
3495 dcerpc_spoolss_ClosePrinter(cli2
->binding_handle
, mem_ctx
, &hPrinter2
, &_result
);
3499 /* close the second remote connection */
3501 cli_shutdown( cli_server2
);
3505 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3507 printf("print_processor_name: %s\n", r
->print_processor_name
);
3510 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3511 TALLOC_CTX
*mem_ctx
, int argc
,
3515 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3516 uint32_t num_procs
, level
= 1, i
;
3517 union spoolss_PrintProcessorInfo
*procs
;
3519 /* Parse the command arguments */
3521 if (argc
< 1 || argc
> 4) {
3522 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3527 environment
= argv
[1];
3531 level
= atoi(argv
[2]);
3534 /* Enumerate Print Processors */
3536 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3537 cli
->srv_name_slash
,
3543 if (!W_ERROR_IS_OK(werror
))
3546 /* Display output */
3548 for (i
= 0; i
< num_procs
; i
++) {
3551 display_proc_info1(&procs
[i
].info1
);
3560 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3562 printf("name_array: %s\n", r
->name_array
);
3565 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3566 TALLOC_CTX
*mem_ctx
, int argc
,
3570 const char *print_processor_name
= "winprint";
3571 uint32_t num_procs
, level
= 1, i
;
3572 union spoolss_PrintProcDataTypesInfo
*procs
;
3574 /* Parse the command arguments */
3576 if (argc
< 1 || argc
> 4) {
3577 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3582 print_processor_name
= argv
[1];
3586 level
= atoi(argv
[2]);
3589 /* Enumerate Print Processor Data Types */
3591 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3592 cli
->srv_name_slash
,
3593 print_processor_name
,
3598 if (!W_ERROR_IS_OK(werror
))
3601 /* Display output */
3603 for (i
= 0; i
< num_procs
; i
++) {
3606 display_proc_data_types_info1(&procs
[i
].info1
);
3615 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3617 printf("monitor_name: %s\n", r
->monitor_name
);
3620 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3622 printf("monitor_name: %s\n", r
->monitor_name
);
3623 printf("environment: %s\n", r
->environment
);
3624 printf("dll_name: %s\n", r
->dll_name
);
3627 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3628 TALLOC_CTX
*mem_ctx
, int argc
,
3632 uint32_t count
, level
= 1, i
;
3633 union spoolss_MonitorInfo
*info
;
3635 /* Parse the command arguments */
3638 printf("Usage: %s [level]\n", argv
[0]);
3643 level
= atoi(argv
[1]);
3646 /* Enumerate Print Monitors */
3648 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3649 cli
->srv_name_slash
,
3654 if (!W_ERROR_IS_OK(werror
)) {
3658 /* Display output */
3660 for (i
= 0; i
< count
; i
++) {
3663 display_monitor1(&info
[i
].info1
);
3666 display_monitor2(&info
[i
].info2
);
3675 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3676 TALLOC_CTX
*mem_ctx
, int argc
,
3681 struct policy_handle handle
, gdi_handle
;
3682 const char *printername
;
3683 struct spoolss_DevmodeContainer devmode_ctr
;
3684 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3686 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3688 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3690 SEC_FLAG_MAXIMUM_ALLOWED
,
3692 if (!W_ERROR_IS_OK(result
)) {
3696 ZERO_STRUCT(devmode_ctr
);
3698 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3703 if (!NT_STATUS_IS_OK(status
)) {
3704 result
= ntstatus_to_werror(status
);
3707 if (!W_ERROR_IS_OK(result
)) {
3712 if (is_valid_policy_hnd(&gdi_handle
)) {
3714 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3716 if (is_valid_policy_hnd(&handle
)) {
3718 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3724 /* List of commands exported by this module */
3725 struct cmd_set spoolss_commands
[] = {
3729 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a print driver", "" },
3730 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a printer", "" },
3731 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver", "" },
3732 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver with files", "" },
3733 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data", "" },
3734 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data for a key", "" },
3735 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer keys", "" },
3736 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate print jobs", "" },
3737 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print job", "" },
3738 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set print job", "" },
3739 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer ports", "" },
3740 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate installed printer drivers", "" },
3741 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printers", "" },
3742 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver data", "" },
3743 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer driver data with keyname", ""},
3744 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver information", "" },
3745 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver upload directory", "" },
3746 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer info", "" },
3747 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3748 { "openprinter_ex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3749 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer driver", "" },
3750 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print processor directory", "" },
3751 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add form", "" },
3752 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set form", "" },
3753 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get form", "" },
3754 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete form", "" },
3755 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate forms", "" },
3756 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer comment", "" },
3757 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printername", "" },
3758 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set REG_SZ printer data", "" },
3759 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Rffpcnex test", "" },
3760 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
.syntax_id
, NULL
, "Printer comparison test", "" },
3761 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processors", "" },
3762 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processor Data Types", "" },
3763 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Monitors", "" },
3764 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
.syntax_id
, NULL
, "Create Printer IC", "" },