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 "../librpc/gen_ndr/ndr_spoolss.h"
29 #include "rpc_client/cli_spoolss.h"
30 #include "rpc_client/init_spoolss.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"
36 #include "popt_common_cmdline.h"
38 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
40 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
41 _cli->srv_name_slash, _arg); \
42 W_ERROR_HAVE_NO_MEMORY(_printername); \
45 /* The version int is used by getdrivers. Note that
46 all architecture strings that support mutliple
47 versions must be grouped together since enumdrivers
48 uses this property to prevent issuing multiple
49 enumdriver calls for the same arch */
52 static const struct print_architecture_table_node archi_table
[]= {
54 {"Windows 4.0", "WIN40", 0 },
55 {"Windows NT x86", "W32X86", 2 },
56 {"Windows NT x86", "W32X86", 3 },
57 {"Windows NT R4000", "W32MIPS", 2 },
58 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
59 {"Windows NT PowerPC", "W32PPC", 2 },
60 {"Windows IA64", "IA64", 3 },
61 {"Windows x64", "x64", 3 },
68 * rpcclient module for SPOOLSS rpc pipe.
70 * This generally just parses and checks command lines, and then calls
71 * a cli_spoolss function.
74 /****************************************************************************
75 function to do the mapping between the long architecture name and
77 ****************************************************************************/
79 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
83 DEBUG(107,("Getting architecture dependent directory\n"));
86 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
87 strcasecmp_m(long_archi
, archi_table
[i
].long_archi
) );
89 if (archi_table
[i
].long_archi
==NULL
) {
90 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
94 /* this might be client code - but shouldn't this be an fstrcpy etc? */
97 DEBUGADD(108,("index: [%d]\n", i
));
98 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
99 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
101 return archi_table
[i
].short_archi
;
104 /****************************************************************************
105 ****************************************************************************/
107 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
109 int argc
, const char **argv
)
112 struct policy_handle hnd
;
113 uint32_t access_mask
= PRINTER_ALL_ACCESS
;
114 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
117 printf("Usage: %s <printername> [access_mask]\n", argv
[0]);
122 sscanf(argv
[2], "%x", &access_mask
);
125 /* Open the printer handle */
127 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
131 if (W_ERROR_IS_OK(werror
)) {
132 printf("Printer %s opened successfully\n", argv
[1]);
133 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &werror
);
135 if (!W_ERROR_IS_OK(werror
)) {
136 printf("Error closing printer handle! (%s)\n",
137 get_dos_error_msg(werror
));
144 /****************************************************************************
145 ****************************************************************************/
147 static WERROR
cmd_spoolss_open_printer(struct rpc_pipe_client
*cli
,
149 int argc
, const char **argv
)
152 struct policy_handle hnd
;
153 uint32_t access_mask
= PRINTER_ALL_ACCESS
;
155 struct spoolss_DevmodeContainer devmode_ctr
;
156 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
158 ZERO_STRUCT(devmode_ctr
);
161 printf("Usage: %s <printername> [access_mask]\n", argv
[0]);
166 sscanf(argv
[2], "%x", &access_mask
);
169 /* Open the printer handle */
171 status
= dcerpc_spoolss_OpenPrinter(b
, mem_ctx
,
178 if (!NT_STATUS_IS_OK(status
)) {
179 return ntstatus_to_werror(status
);
181 if (W_ERROR_IS_OK(werror
)) {
182 printf("Printer %s opened successfully\n", argv
[1]);
183 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &werror
);
185 if (!W_ERROR_IS_OK(werror
)) {
186 printf("Error closing printer handle! (%s)\n",
187 get_dos_error_msg(werror
));
194 /****************************************************************************
195 ****************************************************************************/
197 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
202 printf("\tprintername:[%s]\n", r
->printername
);
203 printf("\tservername:[%s]\n", r
->servername
);
204 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
205 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
206 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
207 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
208 r
->time
.day
, r
->time
.day_of_week
);
209 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
210 r
->time
.second
, r
->time
.millisecond
);
212 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
213 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
215 printf("\tversion:[0x%x]\n", r
->version
);
216 printf("\tfree_build:[0x%x]\n", r
->free_build
);
217 printf("\tspooling:[0x%x]\n", r
->spooling
);
218 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
219 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
220 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
221 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
222 printf("\tjob_error:[0x%x]\n", r
->job_error
);
223 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
224 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
225 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
226 printf("\tchange_id:[0x%x]\n", r
->change_id
);
227 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
228 printf("\tstatus:[0x%x]\n", r
->status
);
229 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
230 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
231 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
232 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
233 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
234 printf("\treserved2:[0x%x]\n", r
->reserved2
);
235 printf("\treserved3:[0x%x]\n", r
->reserved3
);
240 /****************************************************************************
241 ****************************************************************************/
243 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
245 printf("\tflags:[0x%x]\n", r
->flags
);
246 printf("\tname:[%s]\n", r
->name
);
247 printf("\tdescription:[%s]\n", r
->description
);
248 printf("\tcomment:[%s]\n", r
->comment
);
253 /****************************************************************************
254 ****************************************************************************/
256 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
258 printf("\tservername:[%s]\n", r
->servername
);
259 printf("\tprintername:[%s]\n", r
->printername
);
260 printf("\tsharename:[%s]\n", r
->sharename
);
261 printf("\tportname:[%s]\n", r
->portname
);
262 printf("\tdrivername:[%s]\n", r
->drivername
);
263 printf("\tcomment:[%s]\n", r
->comment
);
264 printf("\tlocation:[%s]\n", r
->location
);
265 printf("\tsepfile:[%s]\n", r
->sepfile
);
266 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
267 printf("\tdatatype:[%s]\n", r
->datatype
);
268 printf("\tparameters:[%s]\n", r
->parameters
);
269 printf("\tattributes:[0x%x]\n", r
->attributes
);
270 printf("\tpriority:[0x%x]\n", r
->priority
);
271 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
272 printf("\tstarttime:[0x%x]\n", r
->starttime
);
273 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
274 printf("\tstatus:[0x%x]\n", r
->status
);
275 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
276 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
279 display_sec_desc(r
->secdesc
);
284 /****************************************************************************
285 ****************************************************************************/
287 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
289 display_sec_desc(r
->secdesc
);
294 /****************************************************************************
295 ****************************************************************************/
297 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
299 printf("\tservername:[%s]\n", r
->servername
);
300 printf("\tprintername:[%s]\n", r
->printername
);
301 printf("\tattributes:[0x%x]\n", r
->attributes
);
305 /****************************************************************************
306 ****************************************************************************/
308 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
310 printf("\tprintername:[%s]\n", r
->printername
);
311 printf("\tportname:[%s]\n", r
->portname
);
312 printf("\tattributes:[0x%x]\n", r
->attributes
);
313 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
314 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
318 /****************************************************************************
319 ****************************************************************************/
321 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
323 printf("\tstatus:[0x%x]\n", r
->status
);
327 /****************************************************************************
328 ****************************************************************************/
330 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
332 printf("\tguid:[%s]\n", r
->guid
);
333 printf("\taction:[0x%x]\n", r
->action
);
337 /****************************************************************************
338 ****************************************************************************/
340 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
342 int argc
, const char **argv
)
346 union spoolss_PrinterInfo
*info
;
349 uint32_t flags
= PRINTER_ENUM_LOCAL
;
352 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
357 level
= atoi(argv
[1]);
363 name
= cli
->srv_name_slash
;
367 flags
= atoi(argv
[3]);
370 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
377 if (W_ERROR_IS_OK(result
)) {
380 printf ("No printers returned.\n");
384 for (i
= 0; i
< count
; i
++) {
387 display_print_info0(&info
[i
].info0
);
390 display_print_info1(&info
[i
].info1
);
393 display_print_info2(&info
[i
].info2
);
396 display_print_info3(&info
[i
].info3
);
399 display_print_info4(&info
[i
].info4
);
402 display_print_info5(&info
[i
].info5
);
405 display_print_info6(&info
[i
].info6
);
408 printf("unknown info level %d\n", level
);
418 /****************************************************************************
419 ****************************************************************************/
421 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
423 printf("\tPort Name:\t[%s]\n", r
->port_name
);
426 /****************************************************************************
427 ****************************************************************************/
429 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
431 printf("\tPort Name:\t[%s]\n", r
->port_name
);
432 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
433 printf("\tDescription:\t[%s]\n", r
->description
);
434 printf("\tPort Type:\t" );
436 int comma
= 0; /* hack */
438 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
442 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
443 printf( "%sWrite", comma
? ", " : "" );
446 /* These two have slightly different interpretations
447 on 95/98/ME but I'm disregarding that for now */
448 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
449 printf( "%sRedirected", comma
? ", " : "" );
452 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
453 printf( "%sNet-Attached", comma
? ", " : "" );
457 printf( "[Unset]\n" );
459 printf("\tReserved:\t[%d]\n", r
->reserved
);
463 /****************************************************************************
464 ****************************************************************************/
466 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
467 TALLOC_CTX
*mem_ctx
, int argc
,
473 union spoolss_PortInfo
*info
;
476 printf("Usage: %s [level]\n", argv
[0]);
481 level
= atoi(argv
[1]);
484 /* Enumerate ports */
486 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
492 if (W_ERROR_IS_OK(result
)) {
495 for (i
= 0; i
< count
; i
++) {
498 display_port_info_1(&info
[i
].info1
);
501 display_port_info_2(&info
[i
].info2
);
504 printf("unknown info level %d\n", level
);
513 /****************************************************************************
514 ****************************************************************************/
516 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
518 int argc
, const char **argv
)
520 struct policy_handle pol
;
523 uint32_t info_level
= 2;
524 union spoolss_PrinterInfo info
;
525 struct spoolss_SetPrinterInfoCtr info_ctr
;
526 struct spoolss_SetPrinterInfo2 info2
;
527 const char *printername
, *comment
= NULL
;
528 struct spoolss_DevmodeContainer devmode_ctr
;
529 struct sec_desc_buf secdesc_ctr
;
530 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
532 if (argc
== 1 || argc
> 3) {
533 printf("Usage: %s printername comment\n", argv
[0]);
538 /* Open a printer handle */
543 ZERO_STRUCT(devmode_ctr
);
544 ZERO_STRUCT(secdesc_ctr
);
546 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
548 /* get a printer handle */
549 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
553 if (!W_ERROR_IS_OK(result
))
556 /* Get printer info */
557 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
562 if (!W_ERROR_IS_OK(result
))
566 /* Modify the comment. */
567 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
568 info2
.comment
= comment
;
571 info_ctr
.info
.info2
= &info2
;
573 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
580 if (!NT_STATUS_IS_OK(status
)) {
581 result
= ntstatus_to_werror(status
);
584 if (W_ERROR_IS_OK(result
))
585 printf("Success in setting comment.\n");
588 if (is_valid_policy_hnd(&pol
)) {
590 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
596 /****************************************************************************
597 ****************************************************************************/
599 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
601 int argc
, const char **argv
)
603 struct policy_handle pol
;
606 uint32_t info_level
= 2;
607 union spoolss_PrinterInfo info
;
608 const char *printername
,
609 *new_printername
= NULL
;
610 struct spoolss_SetPrinterInfoCtr info_ctr
;
611 struct spoolss_SetPrinterInfo2 info2
;
612 struct spoolss_DevmodeContainer devmode_ctr
;
613 struct sec_desc_buf secdesc_ctr
;
614 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
616 ZERO_STRUCT(devmode_ctr
);
617 ZERO_STRUCT(secdesc_ctr
);
619 if (argc
== 1 || argc
> 3) {
620 printf("Usage: %s printername new_printername\n", argv
[0]);
625 /* Open a printer handle */
627 new_printername
= argv
[2];
630 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
632 /* get a printer handle */
633 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
637 if (!W_ERROR_IS_OK(result
))
640 /* Get printer info */
641 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
646 if (!W_ERROR_IS_OK(result
))
649 /* Modify the printername. */
650 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
651 info2
.printername
= new_printername
;
654 info_ctr
.info
.info2
= &info2
;
656 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
663 if (!NT_STATUS_IS_OK(status
)) {
664 result
= ntstatus_to_werror(status
);
667 if (W_ERROR_IS_OK(result
))
668 printf("Success in setting printername.\n");
671 if (is_valid_policy_hnd(&pol
)) {
673 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
679 /****************************************************************************
680 ****************************************************************************/
682 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
684 int argc
, const char **argv
)
686 struct policy_handle pol
;
689 const char *printername
;
690 union spoolss_PrinterInfo info
;
691 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
693 if (argc
== 1 || argc
> 3) {
694 printf("Usage: %s <printername> [level]\n", argv
[0]);
698 /* Open a printer handle */
700 level
= atoi(argv
[2]);
703 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
705 /* get a printer handle */
707 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
709 SEC_FLAG_MAXIMUM_ALLOWED
,
711 if (!W_ERROR_IS_OK(result
)) {
715 /* Get printer info */
717 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
722 if (!W_ERROR_IS_OK(result
)) {
726 /* Display printer info */
729 display_print_info0(&info
.info0
);
732 display_print_info1(&info
.info1
);
735 display_print_info2(&info
.info2
);
738 display_print_info3(&info
.info3
);
741 display_print_info4(&info
.info4
);
744 display_print_info5(&info
.info5
);
747 display_print_info6(&info
.info6
);
750 display_print_info7(&info
.info7
);
753 printf("unknown info level %d\n", level
);
757 if (is_valid_policy_hnd(&pol
)) {
759 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
765 /****************************************************************************
766 ****************************************************************************/
768 static void display_reg_value(const char *name
, enum winreg_Type type
, DATA_BLOB blob
)
770 const char *text
= NULL
;
774 if (blob
.length
>= sizeof(uint32_t)) {
775 printf("%s: REG_DWORD: 0x%08x\n", name
, IVAL(blob
.data
,0));
777 printf("%s: REG_DWORD: <invalid>\n", name
);
781 pull_reg_sz(talloc_tos(), &blob
, &text
);
782 printf("%s: REG_SZ: %s\n", name
, text
? text
: "");
785 char *hex
= hex_encode_talloc(NULL
, blob
.data
, blob
.length
);
787 printf("%s: REG_BINARY:", name
);
789 for (i
=0; i
<len
; i
++) {
790 if (hex
[i
] == '\0') {
806 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
807 d_printf("pull_reg_multi_sz failed\n");
811 printf("%s: REG_MULTI_SZ: \n", name
);
812 for (i
=0; values
[i
] != NULL
; i
++) {
813 d_printf("%s\n", values
[i
]);
819 printf("%s: unknown type %d\n", name
, type
);
824 /****************************************************************************
825 ****************************************************************************/
827 static void display_printer_data(const char *v
,
828 enum winreg_Type type
,
833 union spoolss_PrinterData r
;
834 DATA_BLOB blob
= data_blob_const(data
, length
);
836 enum ndr_err_code ndr_err
;
838 result
= pull_spoolss_PrinterData(talloc_tos(), &blob
, &r
, type
);
839 if (!W_ERROR_IS_OK(result
)) {
845 printf("%s: REG_DWORD: 0x%08x\n", v
, r
.value
);
848 printf("%s: REG_SZ: %s\n", v
, r
.string
);
851 char *hex
= hex_encode_talloc(NULL
,
852 r
.binary
.data
, r
.binary
.length
);
854 printf("%s: REG_BINARY:", v
);
856 for (i
=0; i
<len
; i
++) {
857 if (hex
[i
] == '\0') {
869 if (strequal(v
, "OsVersion")) {
870 struct spoolss_OSVersion os
;
871 ndr_err
= ndr_pull_struct_blob(&blob
, talloc_tos(), &os
,
872 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_OSVersion
);
873 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
875 printf("OsMajor: %u\n", os
.major
);
876 printf("OsMinor: %u\n", os
.minor
);
877 printf("OsBuild: %u\n", os
.build
);
878 NDR_PRINT_DEBUG(spoolss_OSVersion
, &os
);
881 if (strequal(v
, "OsVersionEx")) {
882 struct spoolss_OSVersionEx os
;
883 ndr_err
= ndr_pull_struct_blob(&blob
, talloc_tos(), &os
,
884 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_OSVersionEx
);
885 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
886 printf("OsMajor: %u\n", os
.major
);
887 printf("OsMinor: %u\n", os
.minor
);
888 printf("OsBuild: %u\n", os
.build
);
889 printf("ServicePackMajor: %u\n", os
.service_pack_major
);
890 printf("ServicePackMinor: %u\n", os
.service_pack_minor
);
891 NDR_PRINT_DEBUG(spoolss_OSVersionEx
, &os
);
897 printf("%s: REG_MULTI_SZ: ", v
);
898 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
899 printf("%s ", r
.string_array
[i
]);
904 printf("%s: unknown type 0x%02x:\n", v
, type
);
909 /****************************************************************************
910 ****************************************************************************/
912 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
914 int argc
, const char **argv
)
916 struct policy_handle pol
;
919 const char *valuename
;
920 enum winreg_Type type
;
923 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
926 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
927 printf("<printername> of . queries print server\n");
932 /* Open a printer handle */
934 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
935 fstrcpy(printername
, cli
->srv_name_slash
);
937 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
938 cli
->srv_name_slash
, argv
[1]);
940 /* get a printer handle */
942 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
944 SEC_FLAG_MAXIMUM_ALLOWED
,
946 if (!W_ERROR_IS_OK(result
))
949 /* Get printer info */
951 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
958 if (!W_ERROR_IS_OK(result
))
961 /* Display printer data */
963 display_printer_data(valuename
, type
, data
, needed
);
966 if (is_valid_policy_hnd(&pol
)) {
968 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
974 /****************************************************************************
975 ****************************************************************************/
977 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
979 int argc
, const char **argv
)
981 struct policy_handle pol
;
985 const char *valuename
, *keyname
;
987 enum winreg_Type type
;
988 uint8_t *data
= NULL
;
989 uint32_t offered
= 0;
991 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
994 printf("Usage: %s <printername> <keyname> <valuename>\n",
996 printf("<printername> of . queries print server\n");
1002 /* Open a printer handle */
1004 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
1005 fstrcpy(printername
, cli
->srv_name_slash
);
1007 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
1008 cli
->srv_name_slash
, argv
[1]);
1010 /* get a printer handle */
1012 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1014 SEC_FLAG_MAXIMUM_ALLOWED
,
1016 if (!W_ERROR_IS_OK(result
))
1019 /* Get printer info */
1021 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1026 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1035 if (!NT_STATUS_IS_OK(status
)) {
1036 result
= ntstatus_to_werror(status
);
1039 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
1041 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1045 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1056 if (!NT_STATUS_IS_OK(status
)) {
1057 result
= ntstatus_to_werror(status
);
1061 if (!W_ERROR_IS_OK(result
))
1064 /* Display printer data */
1066 display_printer_data(valuename
, type
, data
, needed
);
1070 if (is_valid_policy_hnd(&pol
)) {
1072 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1078 /****************************************************************************
1079 ****************************************************************************/
1081 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1087 printf("Printer Driver Info 1:\n");
1088 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1092 /****************************************************************************
1093 ****************************************************************************/
1095 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1101 printf("Printer Driver Info 2:\n");
1102 printf("\tVersion: [%x]\n", r
->version
);
1103 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1104 printf("\tArchitecture: [%s]\n", r
->architecture
);
1105 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1106 printf("\tDatafile: [%s]\n", r
->data_file
);
1107 printf("\tConfigfile: [%s]\n", r
->config_file
);
1111 /****************************************************************************
1112 ****************************************************************************/
1114 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1122 printf("Printer Driver Info 3:\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
);
1140 /****************************************************************************
1141 ****************************************************************************/
1143 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1151 printf("Printer Driver Info 4:\n");
1152 printf("\tVersion: [%x]\n", r
->version
);
1153 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1154 printf("\tArchitecture: [%s]\n", r
->architecture
);
1155 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1156 printf("\tDatafile: [%s]\n", r
->data_file
);
1157 printf("\tConfigfile: [%s]\n", r
->config_file
);
1158 printf("\tHelpfile: [%s]\n", r
->help_file
);
1160 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1161 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1164 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1165 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1167 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1168 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1173 /****************************************************************************
1174 ****************************************************************************/
1176 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1182 printf("Printer Driver Info 5:\n");
1183 printf("\tVersion: [%x]\n", r
->version
);
1184 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1185 printf("\tArchitecture: [%s]\n", r
->architecture
);
1186 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1187 printf("\tDatafile: [%s]\n", r
->data_file
);
1188 printf("\tConfigfile: [%s]\n", r
->config_file
);
1189 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1190 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1191 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1195 /****************************************************************************
1196 ****************************************************************************/
1198 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1206 printf("Printer Driver Info 6:\n");
1207 printf("\tVersion: [%x]\n", r
->version
);
1208 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1209 printf("\tArchitecture: [%s]\n", r
->architecture
);
1210 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1211 printf("\tDatafile: [%s]\n", r
->data_file
);
1212 printf("\tConfigfile: [%s]\n", r
->config_file
);
1213 printf("\tHelpfile: [%s]\n", r
->help_file
);
1215 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1216 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1219 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1220 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1222 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1223 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1226 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1227 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1228 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1229 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1230 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1231 printf("\tProvider: [%s]\n", r
->provider
);
1236 /****************************************************************************
1237 ****************************************************************************/
1239 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1247 printf("Printer Driver Info 8:\n");
1248 printf("\tVersion: [%x]\n", r
->version
);
1249 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1250 printf("\tArchitecture: [%s]\n", r
->architecture
);
1251 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1252 printf("\tDatafile: [%s]\n", r
->data_file
);
1253 printf("\tConfigfile: [%s]\n", r
->config_file
);
1254 printf("\tHelpfile: [%s]\n", r
->help_file
);
1255 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1256 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1258 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1259 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1262 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1263 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1266 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1267 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1268 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1269 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1270 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1271 printf("\tProvider: [%s]\n", r
->provider
);
1272 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1273 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1274 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1275 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1277 printf("\tInf Path: [%s]\n", r
->inf_path
);
1278 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1279 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1280 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1282 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1283 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1284 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1289 /****************************************************************************
1290 ****************************************************************************/
1292 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1293 TALLOC_CTX
*mem_ctx
,
1294 int argc
, const char **argv
)
1296 struct policy_handle pol
;
1299 const char *printername
;
1301 bool success
= false;
1302 union spoolss_DriverInfo info
;
1303 uint32_t server_major_version
;
1304 uint32_t server_minor_version
;
1305 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1307 if ((argc
== 1) || (argc
> 3)) {
1308 printf("Usage: %s <printername> [level]\n", argv
[0]);
1312 /* get the arguments need to open the printer handle */
1314 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1317 level
= atoi(argv
[2]);
1320 /* Open a printer handle */
1322 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1326 if (!W_ERROR_IS_OK(werror
)) {
1327 printf("Error opening printer handle for %s!\n", printername
);
1331 /* loop through and print driver info level for each architecture */
1333 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1335 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1337 archi_table
[i
].long_archi
,
1340 archi_table
[i
].version
,
1343 &server_major_version
,
1344 &server_minor_version
);
1345 if (!W_ERROR_IS_OK(werror
)) {
1349 /* need at least one success */
1353 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1357 display_print_driver1(&info
.info1
);
1360 display_print_driver2(&info
.info2
);
1363 display_print_driver3(&info
.info3
);
1366 display_print_driver4(&info
.info4
);
1369 display_print_driver5(&info
.info5
);
1372 display_print_driver6(&info
.info6
);
1375 display_print_driver8(&info
.info8
);
1378 printf("unknown info level %d\n", level
);
1385 if (is_valid_policy_hnd(&pol
)) {
1387 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1397 /****************************************************************************
1398 ****************************************************************************/
1400 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1401 TALLOC_CTX
*mem_ctx
,
1402 const char *architecture
,
1407 union spoolss_DriverInfo
*info
= NULL
;
1410 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1411 cli
->srv_name_slash
,
1418 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1419 printf("Server does not support environment [%s]\n",
1428 if (!W_ERROR_IS_OK(werror
)) {
1429 printf("Error getting driver for environment [%s] - %s\n",
1430 architecture
, win_errstr(werror
));
1434 printf("\n[%s]\n", architecture
);
1438 for (j
=0; j
< count
; j
++) {
1439 display_print_driver1(&info
[j
].info1
);
1443 for (j
=0; j
< count
; j
++) {
1444 display_print_driver2(&info
[j
].info2
);
1448 for (j
=0; j
< count
; j
++) {
1449 display_print_driver3(&info
[j
].info3
);
1453 for (j
=0; j
< count
; j
++) {
1454 display_print_driver4(&info
[j
].info4
);
1458 for (j
=0; j
< count
; j
++) {
1459 display_print_driver5(&info
[j
].info5
);
1463 for (j
=0; j
< count
; j
++) {
1464 display_print_driver6(&info
[j
].info6
);
1468 for (j
=0; j
< count
; j
++) {
1469 display_print_driver8(&info
[j
].info8
);
1473 printf("unknown info level %d\n", level
);
1474 return WERR_INVALID_LEVEL
;
1480 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1481 TALLOC_CTX
*mem_ctx
,
1482 int argc
, const char **argv
)
1484 WERROR werror
= WERR_OK
;
1487 const char *architecture
= NULL
;
1490 printf("Usage: enumdrivers [level] [architecture]\n");
1495 level
= atoi(argv
[1]);
1499 architecture
= argv
[2];
1503 return enum_driver_by_architecture(cli
, mem_ctx
,
1508 /* loop through and print driver info level for each architecture */
1509 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1510 /* check to see if we already asked for this architecture string */
1512 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1516 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1517 archi_table
[i
].long_archi
,
1519 if (!W_ERROR_IS_OK(werror
)) {
1527 /****************************************************************************
1528 ****************************************************************************/
1530 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1532 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1535 /****************************************************************************
1536 ****************************************************************************/
1538 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1539 TALLOC_CTX
*mem_ctx
,
1540 int argc
, const char **argv
)
1544 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1547 union spoolss_DriverDirectoryInfo info
;
1549 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1552 printf("Usage: %s [environment]\n", argv
[0]);
1556 /* Get the arguments need to open the printer handle */
1562 /* Get the directory. Only use Info level 1 */
1564 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1565 cli
->srv_name_slash
,
1573 if (!NT_STATUS_IS_OK(status
)) {
1574 return ntstatus_to_werror(status
);
1576 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1578 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1580 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1581 cli
->srv_name_slash
,
1589 if (!NT_STATUS_IS_OK(status
)) {
1590 return ntstatus_to_werror(status
);
1594 if (W_ERROR_IS_OK(result
)) {
1595 display_printdriverdir_1(&info
.info1
);
1601 /****************************************************************************
1602 ****************************************************************************/
1604 static WERROR
cmd_spoolss_getdriverpackagepath(struct rpc_pipe_client
*cli
,
1605 TALLOC_CTX
*mem_ctx
,
1606 int argc
, const char **argv
)
1610 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1613 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1614 const char *package_id
= "";
1615 const char *cab
= NULL
;
1618 printf("Usage: %s [environment] [package_id]\n", argv
[0]);
1622 /* Get the arguments need to open the printer handle */
1629 package_id
= argv
[2];
1633 cab
= talloc_array(mem_ctx
, char, offered
);
1634 status
= dcerpc_spoolss_GetPrinterDriverPackagePath(b
, mem_ctx
,
1635 cli
->srv_name_slash
,
1643 if (!NT_STATUS_IS_OK(status
)) {
1644 return ntstatus_to_werror(status
);
1647 if (W_ERROR_EQUAL(W_ERROR(WIN32_FROM_HRESULT(hresult
)), WERR_INSUFFICIENT_BUFFER
)) {
1649 cab
= talloc_zero_array(mem_ctx
, char, offered
);
1651 status
= dcerpc_spoolss_GetPrinterDriverPackagePath(b
, mem_ctx
,
1652 cli
->srv_name_slash
,
1660 if (!NT_STATUS_IS_OK(status
)) {
1661 return ntstatus_to_werror(status
);
1665 return W_ERROR(WIN32_FROM_HRESULT(hresult
));
1669 /****************************************************************************
1670 ****************************************************************************/
1672 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1673 struct spoolss_AddDriverInfo3
*info
,
1679 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1681 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1683 info
->version
= archi_table
[i
].version
;
1684 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1689 if (archi_table
[i
].long_archi
== NULL
)
1691 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1698 /**************************************************************************
1699 wrapper for strtok to get the next parameter from a delimited list.
1700 Needed to handle the empty parameter string denoted by "NULL"
1701 *************************************************************************/
1703 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1704 const char *delim
, const char **dest
,
1709 /* get the next token */
1710 ptr
= strtok_r(str
, delim
, saveptr
);
1712 /* a string of 'NULL' is used to represent an empty
1713 parameter because two consecutive delimiters
1714 will not return an empty string. See man strtok(3)
1716 if (ptr
&& (strcasecmp_m(ptr
, "NULL") == 0)) {
1721 *dest
= talloc_strdup(mem_ctx
, ptr
);
1727 /********************************************************************************
1728 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1729 string in the form of
1730 <Long Driver Name>:<Driver File Name>:<Data File Name>:\
1731 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1732 <Default Data Type>:<Comma Separated list of Files>
1733 *******************************************************************************/
1735 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1740 char *saveptr
= NULL
;
1741 struct spoolss_StringArray
*deps
;
1742 const char **file_array
= NULL
;
1745 /* fill in the UNISTR fields */
1746 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1747 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1748 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1749 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1750 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1751 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1752 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1754 /* <Comma Separated List of Dependent Files> */
1755 /* save the beginning of the string */
1756 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1759 /* begin to strip out each filename */
1760 str
= strtok_r(str
, ",", &saveptr
);
1762 /* no dependent files, we are done */
1767 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1772 while (str
!= NULL
) {
1774 ok
= add_string_to_array(deps
, str
, &file_array
, &count
);
1778 str
= strtok_r(NULL
, ",", &saveptr
);
1781 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1782 if (!deps
->string
) {
1786 for (i
=0; i
< count
; i
++) {
1787 deps
->string
[i
] = file_array
[i
];
1790 r
->dependent_files
= deps
;
1795 /****************************************************************************
1796 ****************************************************************************/
1798 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1799 TALLOC_CTX
*mem_ctx
,
1800 int argc
, const char **argv
)
1805 struct spoolss_AddDriverInfoCtr info_ctr
;
1806 struct spoolss_AddDriverInfo3 info3
;
1809 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1811 /* parse the command arguments */
1812 if (argc
!= 3 && argc
!= 4)
1814 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1815 printf ("\t<Long Driver Name>:<Driver File Name>:<Data File Name>:\\\n");
1816 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1817 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1818 printf ("\t[version]\n");
1823 /* Fill in the spoolss_AddDriverInfo3 struct */
1826 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1828 printf ("Error Unknown architecture [%s]\n", argv
[1]);
1829 return WERR_INVALID_PARAMETER
;
1832 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1834 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1835 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1837 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1838 return WERR_INVALID_PARAMETER
;
1841 /* if printer driver version specified, override the default version
1842 * used by the architecture. This allows installation of Windows
1843 * 2000 (version 3) printer drivers. */
1846 info3
.version
= atoi(argv
[3]);
1850 info_ctr
.level
= level
;
1851 info_ctr
.info
.info3
= &info3
;
1853 status
= dcerpc_spoolss_AddPrinterDriver(b
, mem_ctx
,
1854 cli
->srv_name_slash
,
1857 if (!NT_STATUS_IS_OK(status
)) {
1858 return ntstatus_to_werror(status
);
1860 if (W_ERROR_IS_OK(result
)) {
1861 printf ("Printer Driver %s successfully installed.\n",
1869 /****************************************************************************
1870 ****************************************************************************/
1872 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1873 TALLOC_CTX
*mem_ctx
,
1874 int argc
, const char **argv
)
1877 struct spoolss_SetPrinterInfoCtr info_ctr
;
1878 struct spoolss_SetPrinterInfo2 info2
;
1880 /* parse the command arguments */
1883 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1887 /* Fill in the DRIVER_INFO_2 struct */
1890 info2
.printername
= argv
[1];
1891 info2
.drivername
= argv
[3];
1892 info2
.sharename
= argv
[2];
1893 info2
.portname
= argv
[4];
1894 info2
.comment
= "Created by rpcclient";
1895 info2
.printprocessor
= "winprint";
1896 info2
.datatype
= "RAW";
1897 info2
.devmode_ptr
= 0;
1898 info2
.secdesc_ptr
= 0;
1899 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1901 info2
.defaultpriority
= 0;
1902 info2
.starttime
= 0;
1903 info2
.untiltime
= 0;
1905 /* These three fields must not be used by AddPrinter()
1906 as defined in the MS Platform SDK documentation..
1910 info2.averageppm = 0;
1914 info_ctr
.info
.info2
= &info2
;
1916 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1918 if (W_ERROR_IS_OK(result
))
1919 printf ("Printer %s successfully installed.\n", argv
[1]);
1924 /****************************************************************************
1925 ****************************************************************************/
1927 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1928 TALLOC_CTX
*mem_ctx
,
1929 int argc
, const char **argv
)
1931 struct policy_handle pol
;
1935 const char *printername
;
1936 union spoolss_PrinterInfo info
;
1937 struct spoolss_SetPrinterInfoCtr info_ctr
;
1938 struct spoolss_SetPrinterInfo2 info2
;
1939 struct spoolss_DevmodeContainer devmode_ctr
;
1940 struct sec_desc_buf secdesc_ctr
;
1941 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1943 ZERO_STRUCT(devmode_ctr
);
1944 ZERO_STRUCT(secdesc_ctr
);
1946 /* parse the command arguments */
1949 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1953 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1955 /* Get a printer handle */
1957 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1961 if (!W_ERROR_IS_OK(result
))
1964 /* Get printer info */
1966 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1971 if (!W_ERROR_IS_OK(result
)) {
1972 printf ("Unable to retrieve printer information!\n");
1976 /* Set the printer driver */
1978 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
1979 info2
.drivername
= argv
[2];
1982 info_ctr
.info
.info2
= &info2
;
1984 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
1991 if (!NT_STATUS_IS_OK(status
)) {
1992 result
= ntstatus_to_werror(status
);
1995 if (!W_ERROR_IS_OK(result
)) {
1996 printf("SetPrinter call failed!\n");
2000 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
2005 if (is_valid_policy_hnd(&pol
)) {
2007 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
2014 /****************************************************************************
2015 ****************************************************************************/
2017 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
2018 TALLOC_CTX
*mem_ctx
,
2019 int argc
, const char **argv
)
2021 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
2023 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2028 const char *arch
= NULL
;
2029 uint32_t delete_flags
= 0;
2031 /* parse the command arguments */
2032 if (argc
< 2 || argc
> 5) {
2033 printf("Usage: %s <driver> [arch] [version] [flags]\n", argv
[0]);
2040 vers
= atoi(argv
[3]);
2041 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
2044 delete_flags
= atoi(argv
[4]);
2046 /* delete the driver for all architectures */
2047 for (i
=0; archi_table
[i
].long_archi
; i
++) {
2049 if (arch
&& !strequal(archi_table
[i
].long_archi
, arch
))
2052 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
2055 /* make the call to remove the driver */
2056 status
= dcerpc_spoolss_DeletePrinterDriverEx(b
, mem_ctx
,
2057 cli
->srv_name_slash
,
2058 archi_table
[i
].long_archi
,
2061 archi_table
[i
].version
,
2063 if (!NT_STATUS_IS_OK(status
)) {
2064 return ntstatus_to_werror(status
);
2066 if ( !W_ERROR_IS_OK(result
) )
2068 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
2069 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
2070 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
2075 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
2076 archi_table
[i
].long_archi
, archi_table
[i
].version
);
2085 /****************************************************************************
2086 ****************************************************************************/
2088 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
2089 TALLOC_CTX
*mem_ctx
,
2090 int argc
, const char **argv
)
2092 WERROR result
= WERR_OK
;
2095 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2097 /* parse the command arguments */
2099 printf ("Usage: %s <driver>\n", argv
[0]);
2103 /* delete the driver for all architectures */
2104 for (i
=0; archi_table
[i
].long_archi
; i
++) {
2107 /* make the call to remove the driver */
2108 status
= dcerpc_spoolss_DeletePrinterDriver(b
, mem_ctx
,
2109 cli
->srv_name_slash
,
2110 archi_table
[i
].long_archi
,
2113 if (!NT_STATUS_IS_OK(status
)) {
2114 result
= ntstatus_to_werror(status
);
2117 if ( !W_ERROR_IS_OK(result
) ) {
2118 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
2119 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
2120 argv
[1], archi_table
[i
].long_archi
,
2121 win_errstr(result
));
2124 printf ("Driver %s removed for arch [%s].\n", argv
[1],
2125 archi_table
[i
].long_archi
);
2132 /****************************************************************************
2133 ****************************************************************************/
2135 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
2136 TALLOC_CTX
*mem_ctx
,
2137 int argc
, const char **argv
)
2141 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
2144 union spoolss_PrintProcessorDirectoryInfo info
;
2146 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2148 /* parse the command arguments */
2150 printf ("Usage: %s [environment]\n", argv
[0]);
2155 environment
= argv
[1];
2158 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2159 cli
->srv_name_slash
,
2167 if (!NT_STATUS_IS_OK(status
)) {
2168 return ntstatus_to_werror(status
);
2170 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2172 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2174 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2175 cli
->srv_name_slash
,
2183 if (!NT_STATUS_IS_OK(status
)) {
2184 return ntstatus_to_werror(status
);
2188 if (W_ERROR_IS_OK(result
)) {
2189 printf("%s\n", info
.info1
.directory_name
);
2195 /****************************************************************************
2196 ****************************************************************************/
2198 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2199 int argc
, const char **argv
)
2201 struct policy_handle handle
;
2204 const char *printername
;
2205 struct spoolss_AddFormInfoCtr info_ctr
;
2206 struct spoolss_AddFormInfo1 info1
;
2207 struct spoolss_AddFormInfo2 info2
;
2209 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2211 /* Parse the command arguments */
2213 if (argc
< 3 || argc
> 5) {
2214 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2218 /* Get a printer handle */
2220 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2222 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2226 if (!W_ERROR_IS_OK(werror
))
2229 /* Dummy up some values for the form data */
2232 level
= atoi(argv
[3]);
2237 info1
.flags
= SPOOLSS_FORM_USER
;
2238 info1
.form_name
= argv
[2];
2239 info1
.size
.width
= 100;
2240 info1
.size
.height
= 100;
2241 info1
.area
.left
= 0;
2242 info1
.area
.top
= 10;
2243 info1
.area
.right
= 20;
2244 info1
.area
.bottom
= 30;
2247 info_ctr
.info
.info1
= &info1
;
2251 info2
.flags
= SPOOLSS_FORM_USER
;
2252 info2
.form_name
= argv
[2];
2253 info2
.size
.width
= 100;
2254 info2
.size
.height
= 100;
2255 info2
.area
.left
= 0;
2256 info2
.area
.top
= 10;
2257 info2
.area
.right
= 20;
2258 info2
.area
.bottom
= 30;
2259 info2
.keyword
= argv
[2];
2260 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2261 info2
.mui_dll
= NULL
;
2262 info2
.ressource_id
= 0;
2263 info2
.display_name
= argv
[2];
2267 info_ctr
.info
.info2
= &info2
;
2271 werror
= WERR_INVALID_PARAMETER
;
2277 status
= dcerpc_spoolss_AddForm(b
, mem_ctx
,
2281 if (!NT_STATUS_IS_OK(status
)) {
2282 werror
= ntstatus_to_werror(status
);
2286 if (is_valid_policy_hnd(&handle
)) {
2288 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2294 /****************************************************************************
2295 ****************************************************************************/
2297 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2298 int argc
, const char **argv
)
2300 struct policy_handle handle
;
2303 const char *printername
;
2304 struct spoolss_AddFormInfoCtr info_ctr
;
2305 struct spoolss_AddFormInfo1 info1
;
2306 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2308 /* Parse the command arguments */
2311 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2315 /* Get a printer handle */
2317 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2319 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2321 SEC_FLAG_MAXIMUM_ALLOWED
,
2323 if (!W_ERROR_IS_OK(werror
))
2326 /* Dummy up some values for the form data */
2328 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2329 info1
.size
.width
= 100;
2330 info1
.size
.height
= 100;
2331 info1
.area
.left
= 0;
2332 info1
.area
.top
= 1000;
2333 info1
.area
.right
= 2000;
2334 info1
.area
.bottom
= 3000;
2335 info1
.form_name
= argv
[2];
2337 info_ctr
.info
.info1
= &info1
;
2342 status
= dcerpc_spoolss_SetForm(b
, mem_ctx
,
2347 if (!NT_STATUS_IS_OK(status
)) {
2348 werror
= ntstatus_to_werror(status
);
2352 if (is_valid_policy_hnd(&handle
)) {
2354 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2360 /****************************************************************************
2361 ****************************************************************************/
2363 static const char *get_form_flag(int form_flag
)
2365 switch (form_flag
) {
2366 case SPOOLSS_FORM_USER
:
2368 case SPOOLSS_FORM_BUILTIN
:
2369 return "FORM_BUILTIN";
2370 case SPOOLSS_FORM_PRINTER
:
2371 return "FORM_PRINTER";
2377 /****************************************************************************
2378 ****************************************************************************/
2380 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2383 "\tflag: %s (%d)\n" \
2384 "\twidth: %d, length: %d\n" \
2385 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2386 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2387 r
->size
.width
, r
->size
.height
,
2388 r
->area
.left
, r
->area
.right
,
2389 r
->area
.top
, r
->area
.bottom
);
2392 /****************************************************************************
2393 ****************************************************************************/
2395 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2398 "\tflag: %s (%d)\n" \
2399 "\twidth: %d, length: %d\n" \
2400 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2401 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2402 r
->size
.width
, r
->size
.height
,
2403 r
->area
.left
, r
->area
.right
,
2404 r
->area
.top
, r
->area
.bottom
);
2405 printf("\tkeyword: %s\n", r
->keyword
);
2406 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2407 printf("\tmui_dll: %s\n", r
->mui_dll
);
2408 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2409 printf("\tdisplay_name: %s\n", r
->display_name
);
2410 printf("\tlang_id: %d\n", r
->lang_id
);
2414 /****************************************************************************
2415 ****************************************************************************/
2417 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2418 int argc
, const char **argv
)
2420 struct policy_handle handle
;
2423 const char *printername
;
2425 uint32_t offered
= 0;
2426 union spoolss_FormInfo info
;
2429 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2431 /* Parse the command arguments */
2433 if (argc
< 3 || argc
> 5) {
2434 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2438 /* Get a printer handle */
2440 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2442 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2444 SEC_FLAG_MAXIMUM_ALLOWED
,
2446 if (!W_ERROR_IS_OK(werror
))
2450 level
= atoi(argv
[3]);
2455 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2464 if (!NT_STATUS_IS_OK(status
)) {
2465 werror
= ntstatus_to_werror(status
);
2468 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2469 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2471 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2480 if (!NT_STATUS_IS_OK(status
)) {
2481 werror
= ntstatus_to_werror(status
);
2486 if (!W_ERROR_IS_OK(werror
)) {
2492 display_form_info1(&info
.info1
);
2495 display_form_info2(&info
.info2
);
2500 if (is_valid_policy_hnd(&handle
)) {
2502 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2508 /****************************************************************************
2509 ****************************************************************************/
2511 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2512 TALLOC_CTX
*mem_ctx
, int argc
,
2515 struct policy_handle handle
;
2518 const char *printername
;
2519 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2521 /* Parse the command arguments */
2524 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2528 /* Get a printer handle */
2530 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2532 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2534 SEC_FLAG_MAXIMUM_ALLOWED
,
2536 if (!W_ERROR_IS_OK(werror
))
2539 /* Delete the form */
2541 status
= dcerpc_spoolss_DeleteForm(b
, mem_ctx
,
2545 if (!NT_STATUS_IS_OK(status
)) {
2546 werror
= ntstatus_to_werror(status
);
2551 if (is_valid_policy_hnd(&handle
)) {
2553 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2559 /****************************************************************************
2560 ****************************************************************************/
2562 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2563 TALLOC_CTX
*mem_ctx
, int argc
,
2566 struct policy_handle handle
;
2568 const char *printername
;
2569 uint32_t num_forms
, level
= 1, i
;
2570 union spoolss_FormInfo
*forms
;
2571 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2573 /* Parse the command arguments */
2575 if (argc
< 2 || argc
> 4) {
2576 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2580 /* Get a printer handle */
2582 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2584 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2586 SEC_FLAG_MAXIMUM_ALLOWED
,
2588 if (!W_ERROR_IS_OK(werror
))
2592 level
= atoi(argv
[2]);
2595 /* Enumerate forms */
2597 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2604 if (!W_ERROR_IS_OK(werror
))
2607 /* Display output */
2609 for (i
= 0; i
< num_forms
; i
++) {
2612 display_form_info1(&forms
[i
].info1
);
2615 display_form_info2(&forms
[i
].info2
);
2621 if (is_valid_policy_hnd(&handle
)) {
2623 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2629 /****************************************************************************
2630 ****************************************************************************/
2632 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2633 TALLOC_CTX
*mem_ctx
,
2634 int argc
, const char **argv
)
2638 const char *printername
;
2639 struct policy_handle pol
= { 0, };
2640 union spoolss_PrinterInfo info
;
2641 enum winreg_Type type
;
2642 union spoolss_PrinterData data
;
2644 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2646 /* parse the command arguments */
2648 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2649 " <value> <data>\n",
2654 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2658 if (strequal(argv
[2], "string")) {
2662 if (strequal(argv
[2], "binary")) {
2666 if (strequal(argv
[2], "dword")) {
2670 if (strequal(argv
[2], "multistring")) {
2671 type
= REG_MULTI_SZ
;
2674 if (type
== REG_NONE
) {
2675 printf("Unknown data type: %s\n", argv
[2]);
2676 result
= WERR_INVALID_PARAMETER
;
2680 /* get a printer handle */
2682 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2684 SEC_FLAG_MAXIMUM_ALLOWED
,
2686 if (!W_ERROR_IS_OK(result
)) {
2690 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2695 if (!W_ERROR_IS_OK(result
)) {
2699 printf("%s\n", current_timestring(mem_ctx
, true));
2700 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2702 /* Set the printer data */
2706 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2707 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2710 data
.value
= strtoul(argv
[4], NULL
, 10);
2713 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2715 case REG_MULTI_SZ
: {
2718 const char **strings
= NULL
;
2722 for (i
=4; i
<argc
; i
++) {
2723 if (strcmp(argv
[i
], "NULL") == 0) {
2726 if (!add_string_to_array(mem_ctx
, argv
[i
],
2729 result
= WERR_NOT_ENOUGH_MEMORY
;
2733 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2734 if (!data
.string_array
) {
2735 result
= WERR_NOT_ENOUGH_MEMORY
;
2738 for (i
=0; i
< num_strings
; i
++) {
2739 data
.string_array
[i
] = strings
[i
];
2744 printf("Unknown data type: %s\n", argv
[2]);
2745 result
= WERR_INVALID_PARAMETER
;
2749 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2750 if (!W_ERROR_IS_OK(result
)) {
2754 status
= dcerpc_spoolss_SetPrinterData(b
, mem_ctx
,
2756 argv
[3], /* value_name */
2761 if (!NT_STATUS_IS_OK(status
)) {
2762 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2763 result
= ntstatus_to_werror(status
);
2766 if (!W_ERROR_IS_OK(result
)) {
2767 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2770 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2772 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2777 if (!W_ERROR_IS_OK(result
)) {
2781 printf("%s\n", current_timestring(mem_ctx
, true));
2782 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2786 if (is_valid_policy_hnd(&pol
)) {
2788 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
2794 /****************************************************************************
2795 ****************************************************************************/
2797 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2799 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2800 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2804 /****************************************************************************
2805 ****************************************************************************/
2807 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2809 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2810 r
->position
, r
->job_id
,
2811 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2812 r
->total_pages
, r
->size
);
2815 /****************************************************************************
2816 ****************************************************************************/
2818 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2820 printf("jobid[%d], next_jobid[%d]\n",
2821 r
->job_id
, r
->next_job_id
);
2824 /****************************************************************************
2825 ****************************************************************************/
2827 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2829 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2830 r
->position
, r
->job_id
,
2831 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2832 r
->total_pages
, r
->size
, r
->size_high
);
2835 /****************************************************************************
2836 ****************************************************************************/
2838 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2839 TALLOC_CTX
*mem_ctx
, int argc
,
2843 uint32_t level
= 1, count
, i
;
2844 const char *printername
;
2845 struct policy_handle hnd
;
2846 union spoolss_JobInfo
*info
;
2847 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2849 if (argc
< 2 || argc
> 3) {
2850 printf("Usage: %s printername [level]\n", argv
[0]);
2855 level
= atoi(argv
[2]);
2858 /* Open printer handle */
2860 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2862 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2864 SEC_FLAG_MAXIMUM_ALLOWED
,
2866 if (!W_ERROR_IS_OK(result
))
2869 /* Enumerate ports */
2871 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2879 if (!W_ERROR_IS_OK(result
)) {
2883 for (i
= 0; i
< count
; i
++) {
2886 display_job_info1(&info
[i
].info1
);
2889 display_job_info2(&info
[i
].info2
);
2892 d_printf("unknown info level %d\n", level
);
2898 if (is_valid_policy_hnd(&hnd
)) {
2900 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2906 /****************************************************************************
2907 ****************************************************************************/
2909 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2910 TALLOC_CTX
*mem_ctx
, int argc
,
2914 const char *printername
;
2915 struct policy_handle hnd
;
2918 union spoolss_JobInfo info
;
2919 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2921 if (argc
< 3 || argc
> 4) {
2922 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2926 job_id
= atoi(argv
[2]);
2929 level
= atoi(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
)) {
2944 /* Enumerate ports */
2946 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2953 if (!W_ERROR_IS_OK(result
)) {
2959 display_job_info1(&info
.info1
);
2962 display_job_info2(&info
.info2
);
2965 display_job_info3(&info
.info3
);
2968 display_job_info4(&info
.info4
);
2971 d_printf("unknown info level %d\n", level
);
2976 if (is_valid_policy_hnd(&hnd
)) {
2978 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2984 /****************************************************************************
2985 ****************************************************************************/
2989 enum spoolss_JobControl val
;
2991 {"PAUSE", SPOOLSS_JOB_CONTROL_PAUSE
},
2992 {"RESUME", SPOOLSS_JOB_CONTROL_RESUME
},
2993 {"CANCEL", SPOOLSS_JOB_CONTROL_CANCEL
},
2994 {"RESTART", SPOOLSS_JOB_CONTROL_RESTART
},
2995 {"DELETE", SPOOLSS_JOB_CONTROL_DELETE
},
2996 {"SEND_TO_PRINTER", SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER
},
2997 {"EJECTED", SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED
},
2998 {"RETAIN", SPOOLSS_JOB_CONTROL_RETAIN
},
2999 {"RELEASE", SPOOLSS_JOB_CONTROL_RELEASE
}
3002 static enum spoolss_JobControl
parse_setjob_command(const char *cmd
)
3006 for (i
= 0; i
< sizeof(cmdvals
)/sizeof(cmdvals
[0]); i
++) {
3007 if (strequal(cmdvals
[i
].name
, cmd
)) {
3008 return cmdvals
[i
].val
;
3011 return (enum spoolss_JobControl
)atoi(cmd
);
3014 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
3015 TALLOC_CTX
*mem_ctx
, int argc
,
3020 const char *printername
;
3021 struct policy_handle hnd
;
3023 enum spoolss_JobControl command
;
3024 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3027 printf("Usage: %s printername job_id command\n", argv
[0]);
3028 printf("command = [PAUSE|RESUME|CANCEL|RESTART|DELETE|"
3029 "SEND_TO_PRINTER|EJECTED|RETAIN|RELEASE]\n");
3033 job_id
= atoi(argv
[2]);
3034 command
= parse_setjob_command(argv
[3]);
3036 /* Open printer handle */
3038 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3040 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3042 SEC_FLAG_MAXIMUM_ALLOWED
,
3044 if (!W_ERROR_IS_OK(result
)) {
3050 status
= dcerpc_spoolss_SetJob(b
, mem_ctx
,
3056 if (!NT_STATUS_IS_OK(status
)) {
3057 result
= ntstatus_to_werror(status
);
3060 if (!W_ERROR_IS_OK(result
)) {
3065 if (is_valid_policy_hnd(&hnd
)) {
3067 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3073 /****************************************************************************
3074 ****************************************************************************/
3076 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
3077 TALLOC_CTX
*mem_ctx
, int argc
,
3082 const char *printername
;
3083 struct policy_handle hnd
;
3084 uint32_t value_needed
;
3085 enum winreg_Type type
;
3086 uint32_t data_needed
;
3087 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3088 struct spoolss_EnumPrinterData r
;
3091 printf("Usage: %s printername\n", argv
[0]);
3095 /* Open printer handle */
3097 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3099 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3101 SEC_FLAG_MAXIMUM_ALLOWED
,
3103 if (!W_ERROR_IS_OK(result
)) {
3107 /* Enumerate data */
3110 r
.in
.enum_index
= 0;
3111 r
.in
.value_offered
= 0;
3112 r
.in
.data_offered
= 0;
3113 r
.out
.value_name
= NULL
;
3114 r
.out
.value_needed
= &value_needed
;
3117 r
.out
.data_needed
= &data_needed
;
3119 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3120 if (!NT_STATUS_IS_OK(status
)) {
3121 result
= ntstatus_to_werror(status
);
3125 if (!W_ERROR_IS_OK(r
.out
.result
)) {
3126 result
= r
.out
.result
;
3130 r
.in
.data_offered
= *r
.out
.data_needed
;
3131 r
.in
.value_offered
= *r
.out
.value_needed
;
3132 r
.out
.data
= talloc_zero_array(mem_ctx
, uint8_t, r
.in
.data_offered
);
3133 r
.out
.value_name
= talloc_zero_array(mem_ctx
, char, r
.in
.value_offered
);
3137 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3138 if (!NT_STATUS_IS_OK(status
)) {
3139 result
= ntstatus_to_werror(status
);
3143 if (W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
3150 display_reg_value(r
.out
.value_name
, *r
.out
.type
,
3151 data_blob_const(r
.out
.data
, r
.in
.data_offered
));
3153 } while (W_ERROR_IS_OK(r
.out
.result
));
3156 if (is_valid_policy_hnd(&hnd
)) {
3158 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3164 /****************************************************************************
3165 ****************************************************************************/
3167 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
3168 TALLOC_CTX
*mem_ctx
, int argc
,
3173 const char *printername
;
3174 struct policy_handle hnd
;
3176 struct spoolss_PrinterEnumValues
*info
;
3177 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3180 printf("Usage: %s printername <keyname>\n", argv
[0]);
3184 /* Open printer handle */
3186 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3188 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3190 SEC_FLAG_MAXIMUM_ALLOWED
,
3192 if (!W_ERROR_IS_OK(result
)) {
3196 /* Enumerate subkeys */
3198 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
3204 if (!W_ERROR_IS_OK(result
)) {
3208 for (i
=0; i
< count
; i
++) {
3209 display_printer_data(info
[i
].value_name
,
3212 info
[i
].data
->length
);
3216 if (is_valid_policy_hnd(&hnd
)) {
3218 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3224 /****************************************************************************
3225 ****************************************************************************/
3227 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
3228 TALLOC_CTX
*mem_ctx
, int argc
,
3232 const char *printername
;
3233 const char *keyname
= NULL
;
3234 struct policy_handle hnd
;
3235 const char **key_buffer
= NULL
;
3237 uint32_t offered
= 0;
3238 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3240 if (argc
< 2 || argc
> 4) {
3241 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3252 offered
= atoi(argv
[3]);
3255 /* Open printer handle */
3257 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3259 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3261 SEC_FLAG_MAXIMUM_ALLOWED
,
3263 if (!W_ERROR_IS_OK(result
)) {
3267 /* Enumerate subkeys */
3269 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3275 if (!W_ERROR_IS_OK(result
)) {
3279 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3280 printf("%s\n", key_buffer
[i
]);
3285 if (is_valid_policy_hnd(&hnd
)) {
3287 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3293 /****************************************************************************
3294 ****************************************************************************/
3296 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3297 TALLOC_CTX
*mem_ctx
, int argc
,
3300 const char *printername
;
3301 const char *clientname
;
3302 struct policy_handle hnd
= { 0, };
3305 struct spoolss_NotifyOption option
;
3306 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3309 printf("Usage: %s printername\n", argv
[0]);
3316 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3318 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3320 SEC_FLAG_MAXIMUM_ALLOWED
,
3322 if (!W_ERROR_IS_OK(result
)) {
3323 printf("Error opening %s\n", argv
[1]);
3327 /* Create spool options */
3332 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3333 if (option
.types
== NULL
) {
3334 result
= WERR_NOT_ENOUGH_MEMORY
;
3338 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3339 option
.types
[0].count
= 1;
3340 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3341 if (option
.types
[0].fields
== NULL
) {
3342 result
= WERR_NOT_ENOUGH_MEMORY
;
3345 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3347 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3348 option
.types
[1].count
= 1;
3349 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3350 if (option
.types
[1].fields
== NULL
) {
3351 result
= WERR_NOT_ENOUGH_MEMORY
;
3354 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3356 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", lp_netbios_name());
3358 result
= WERR_NOT_ENOUGH_MEMORY
;
3364 status
= dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(b
, mem_ctx
,
3372 if (!NT_STATUS_IS_OK(status
)) {
3373 result
= ntstatus_to_werror(status
);
3376 if (!W_ERROR_IS_OK(result
)) {
3377 printf("Error rffpcnex %s\n", argv
[1]);
3382 if (is_valid_policy_hnd(&hnd
)) {
3384 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3390 /****************************************************************************
3391 ****************************************************************************/
3393 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3394 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3396 union spoolss_PrinterInfo info1
, info2
;
3398 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3400 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3401 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3406 if ( !W_ERROR_IS_OK(werror
) ) {
3407 printf("failed (%s)\n", win_errstr(werror
));
3408 talloc_destroy(mem_ctx
);
3413 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3414 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3419 if ( !W_ERROR_IS_OK(werror
) ) {
3420 printf("failed (%s)\n", win_errstr(werror
));
3421 talloc_destroy(mem_ctx
);
3426 talloc_destroy(mem_ctx
);
3431 /****************************************************************************
3432 ****************************************************************************/
3434 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3435 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3437 union spoolss_PrinterInfo info1
, info2
;
3439 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3440 struct security_descriptor
*sd1
, *sd2
;
3444 printf("Retrieving printer security for %s...", cli1
->desthost
);
3445 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3450 if ( !W_ERROR_IS_OK(werror
) ) {
3451 printf("failed (%s)\n", win_errstr(werror
));
3457 printf("Retrieving printer security for %s...", cli2
->desthost
);
3458 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3463 if ( !W_ERROR_IS_OK(werror
) ) {
3464 printf("failed (%s)\n", win_errstr(werror
));
3473 sd1
= info1
.info3
.secdesc
;
3474 sd2
= info2
.info3
.secdesc
;
3476 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3477 printf("NULL secdesc!\n");
3482 if (!security_descriptor_equal( sd1
, sd2
) ) {
3483 printf("Security Descriptors *not* equal!\n");
3488 printf("Security descriptors match\n");
3491 talloc_destroy(mem_ctx
);
3496 /****************************************************************************
3497 ****************************************************************************/
3499 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3500 TALLOC_CTX
*mem_ctx
, int argc
,
3503 const char *printername
;
3504 char *printername_path
= NULL
;
3505 struct cli_state
*cli_server2
= NULL
;
3506 struct rpc_pipe_client
*cli2
= NULL
;
3507 struct policy_handle hPrinter1
, hPrinter2
;
3512 printf("Usage: %s <printer> <server>\n", argv
[0]);
3516 printername
= argv
[1];
3518 /* first get the connection to the remote server */
3520 nt_status
= cli_full_connection(&cli_server2
, lp_netbios_name(), argv
[2],
3523 get_cmdline_auth_info_username(
3524 popt_get_cmdline_auth_info()),
3526 get_cmdline_auth_info_password(
3527 popt_get_cmdline_auth_info()),
3528 get_cmdline_auth_info_use_kerberos(
3529 popt_get_cmdline_auth_info()) ?
3530 CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3531 get_cmdline_auth_info_signing_state(
3532 popt_get_cmdline_auth_info()));
3534 if ( !NT_STATUS_IS_OK(nt_status
) )
3535 return WERR_GEN_FAILURE
;
3537 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
,
3539 if (!NT_STATUS_IS_OK(nt_status
)) {
3540 printf("failed to open spoolss pipe on server %s (%s)\n",
3541 argv
[2], nt_errstr(nt_status
));
3542 return WERR_GEN_FAILURE
;
3545 /* now open up both printers */
3547 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3549 printf("Opening %s...", printername_path
);
3551 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3555 if ( !W_ERROR_IS_OK(werror
) ) {
3556 printf("failed (%s)\n", win_errstr(werror
));
3561 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3563 printf("Opening %s...", printername_path
);
3564 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3568 if ( !W_ERROR_IS_OK(werror
) ) {
3569 printf("failed (%s)\n", win_errstr(werror
));
3574 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3575 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3577 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3584 printf("Closing printers...");
3587 dcerpc_spoolss_ClosePrinter(cli
->binding_handle
, mem_ctx
, &hPrinter1
, &_result
);
3588 dcerpc_spoolss_ClosePrinter(cli2
->binding_handle
, mem_ctx
, &hPrinter2
, &_result
);
3592 /* close the second remote connection */
3594 cli_shutdown( cli_server2
);
3598 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3600 printf("print_processor_name: %s\n", r
->print_processor_name
);
3603 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3604 TALLOC_CTX
*mem_ctx
, int argc
,
3608 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3609 uint32_t num_procs
, level
= 1, i
;
3610 union spoolss_PrintProcessorInfo
*procs
;
3612 /* Parse the command arguments */
3614 if (argc
< 1 || argc
> 4) {
3615 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3620 environment
= argv
[1];
3624 level
= atoi(argv
[2]);
3627 /* Enumerate Print Processors */
3629 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3630 cli
->srv_name_slash
,
3636 if (!W_ERROR_IS_OK(werror
))
3639 /* Display output */
3641 for (i
= 0; i
< num_procs
; i
++) {
3644 display_proc_info1(&procs
[i
].info1
);
3653 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3655 printf("name_array: %s\n", r
->name_array
);
3658 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3659 TALLOC_CTX
*mem_ctx
, int argc
,
3663 const char *print_processor_name
= "winprint";
3664 uint32_t num_procs
, level
= 1, i
;
3665 union spoolss_PrintProcDataTypesInfo
*procs
;
3667 /* Parse the command arguments */
3669 if (argc
< 1 || argc
> 4) {
3670 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3675 print_processor_name
= argv
[1];
3679 level
= atoi(argv
[2]);
3682 /* Enumerate Print Processor Data Types */
3684 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3685 cli
->srv_name_slash
,
3686 print_processor_name
,
3691 if (!W_ERROR_IS_OK(werror
))
3694 /* Display output */
3696 for (i
= 0; i
< num_procs
; i
++) {
3699 display_proc_data_types_info1(&procs
[i
].info1
);
3708 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3710 printf("monitor_name: %s\n", r
->monitor_name
);
3713 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3715 printf("monitor_name: %s\n", r
->monitor_name
);
3716 printf("environment: %s\n", r
->environment
);
3717 printf("dll_name: %s\n", r
->dll_name
);
3720 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3721 TALLOC_CTX
*mem_ctx
, int argc
,
3725 uint32_t count
, level
= 1, i
;
3726 union spoolss_MonitorInfo
*info
;
3728 /* Parse the command arguments */
3731 printf("Usage: %s [level]\n", argv
[0]);
3736 level
= atoi(argv
[1]);
3739 /* Enumerate Print Monitors */
3741 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3742 cli
->srv_name_slash
,
3747 if (!W_ERROR_IS_OK(werror
)) {
3751 /* Display output */
3753 for (i
= 0; i
< count
; i
++) {
3756 display_monitor1(&info
[i
].info1
);
3759 display_monitor2(&info
[i
].info2
);
3768 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3769 TALLOC_CTX
*mem_ctx
, int argc
,
3774 struct policy_handle handle
, gdi_handle
;
3775 const char *printername
;
3776 struct spoolss_DevmodeContainer devmode_ctr
;
3777 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3779 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3781 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3783 SEC_FLAG_MAXIMUM_ALLOWED
,
3785 if (!W_ERROR_IS_OK(result
)) {
3789 ZERO_STRUCT(devmode_ctr
);
3791 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3796 if (!NT_STATUS_IS_OK(status
)) {
3797 result
= ntstatus_to_werror(status
);
3800 if (!W_ERROR_IS_OK(result
)) {
3805 if (is_valid_policy_hnd(&gdi_handle
)) {
3807 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3809 if (is_valid_policy_hnd(&handle
)) {
3811 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3817 static WERROR
cmd_spoolss_play_gdi_script_on_printer_ic(struct rpc_pipe_client
*cli
,
3818 TALLOC_CTX
*mem_ctx
, int argc
,
3823 struct policy_handle handle
, gdi_handle
;
3824 const char *printername
;
3825 struct spoolss_DevmodeContainer devmode_ctr
;
3826 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3830 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3832 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3834 SEC_FLAG_MAXIMUM_ALLOWED
,
3836 if (!W_ERROR_IS_OK(result
)) {
3840 ZERO_STRUCT(devmode_ctr
);
3842 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3847 if (!NT_STATUS_IS_OK(status
)) {
3848 result
= ntstatus_to_werror(status
);
3851 if (!W_ERROR_IS_OK(result
)) {
3855 in
= data_blob_string_const("");
3856 out
= data_blob_talloc_zero(mem_ctx
, 4);
3858 status
= dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b
, mem_ctx
,
3866 if (!NT_STATUS_IS_OK(status
)) {
3867 result
= ntstatus_to_werror(status
);
3870 if (!W_ERROR_IS_OK(result
)) {
3874 count
= IVAL(out
.data
, 0);
3876 out
= data_blob_talloc_zero(mem_ctx
,
3877 count
* sizeof(struct UNIVERSAL_FONT_ID
) + 4);
3879 status
= dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b
, mem_ctx
,
3887 if (!NT_STATUS_IS_OK(status
)) {
3888 result
= ntstatus_to_werror(status
);
3891 if (!W_ERROR_IS_OK(result
)) {
3896 enum ndr_err_code ndr_err
;
3897 struct UNIVERSAL_FONT_ID_ctr r
;
3899 ndr_err
= ndr_pull_struct_blob(&out
, mem_ctx
, &r
,
3900 (ndr_pull_flags_fn_t
)ndr_pull_UNIVERSAL_FONT_ID_ctr
);
3901 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
3902 NDR_PRINT_DEBUG(UNIVERSAL_FONT_ID_ctr
, &r
);
3907 if (is_valid_policy_hnd(&gdi_handle
)) {
3909 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3911 if (is_valid_policy_hnd(&handle
)) {
3913 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3919 /* List of commands exported by this module */
3920 struct cmd_set spoolss_commands
[] = {
3924 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
, NULL
, "Add a print driver", "" },
3925 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
, NULL
, "Add a printer", "" },
3926 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
, NULL
, "Delete a printer driver", "" },
3927 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
, NULL
, "Delete a printer driver with files", "" },
3928 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
, NULL
, "Enumerate printer data", "" },
3929 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
, NULL
, "Enumerate printer data for a key", "" },
3930 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
, NULL
, "Enumerate printer keys", "" },
3931 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
, NULL
, "Enumerate print jobs", "" },
3932 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
, NULL
, "Get print job", "" },
3933 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
, NULL
, "Set print job", "" },
3934 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
, NULL
, "Enumerate printer ports", "" },
3935 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
, NULL
, "Enumerate installed printer drivers", "" },
3936 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
, NULL
, "Enumerate printers", "" },
3937 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
, NULL
, "Get print driver data", "" },
3938 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
, NULL
, "Get printer driver data with keyname", ""},
3939 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
, NULL
, "Get print driver information", "" },
3940 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
, NULL
, "Get print driver upload directory", "" },
3941 { "getdriverpackagepath", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverpackagepath
, &ndr_table_spoolss
, NULL
, "Get print driver package download directory", "" },
3942 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
, NULL
, "Get printer info", "" },
3943 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer
, &ndr_table_spoolss
, NULL
, "Open printer handle", "" },
3944 { "openprinter_ex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
, NULL
, "Open printer handle", "" },
3945 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
, NULL
, "Set printer driver", "" },
3946 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
, NULL
, "Get print processor directory", "" },
3947 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
, NULL
, "Add form", "" },
3948 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
, NULL
, "Set form", "" },
3949 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
, NULL
, "Get form", "" },
3950 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
, NULL
, "Delete form", "" },
3951 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
, NULL
, "Enumerate forms", "" },
3952 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
, NULL
, "Set printer comment", "" },
3953 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
, NULL
, "Set printername", "" },
3954 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
, NULL
, "Set REG_SZ printer data", "" },
3955 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
, NULL
, "Rffpcnex test", "" },
3956 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
, NULL
, "Printer comparison test", "" },
3957 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
, NULL
, "Enumerate Print Processors", "" },
3958 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
, NULL
, "Enumerate Print Processor Data Types", "" },
3959 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
, NULL
, "Enumerate Print Monitors", "" },
3960 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
, NULL
, "Create Printer IC", "" },
3961 { "playgdiscriptonprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_play_gdi_script_on_printer_ic
, &ndr_table_spoolss
, NULL
, "Create Printer IC", "" },