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"
28 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
30 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
31 _cli->srv_name_slash, _arg); \
32 W_ERROR_HAVE_NO_MEMORY(_printername); \
35 /* The version int is used by getdrivers. Note that
36 all architecture strings that support mutliple
37 versions must be grouped together since enumdrivers
38 uses this property to prevent issuing multiple
39 enumdriver calls for the same arch */
42 static const struct print_architecture_table_node archi_table
[]= {
44 {"Windows 4.0", "WIN40", 0 },
45 {"Windows NT x86", "W32X86", 2 },
46 {"Windows NT x86", "W32X86", 3 },
47 {"Windows NT R4000", "W32MIPS", 2 },
48 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
49 {"Windows NT PowerPC", "W32PPC", 2 },
50 {"Windows IA64", "IA64", 3 },
51 {"Windows x64", "x64", 3 },
58 * rpcclient module for SPOOLSS rpc pipe.
60 * This generally just parses and checks command lines, and then calls
61 * a cli_spoolss function.
64 /****************************************************************************
65 function to do the mapping between the long architecture name and
67 ****************************************************************************/
69 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
73 DEBUG(107,("Getting architecture dependant directory\n"));
76 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
77 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
79 if (archi_table
[i
].long_archi
==NULL
) {
80 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
84 /* this might be client code - but shouldn't this be an fstrcpy etc? */
87 DEBUGADD(108,("index: [%d]\n", i
));
88 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
89 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
91 return archi_table
[i
].short_archi
;
94 /****************************************************************************
95 ****************************************************************************/
97 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
99 int argc
, const char **argv
)
102 struct policy_handle hnd
;
105 printf("Usage: %s <printername>\n", argv
[0]);
110 return WERR_GENERAL_FAILURE
;
112 /* Open the printer handle */
114 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
118 if (W_ERROR_IS_OK(werror
)) {
119 printf("Printer %s opened successfully\n", argv
[1]);
120 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
122 if (!W_ERROR_IS_OK(werror
)) {
123 printf("Error closing printer handle! (%s)\n",
124 get_dos_error_msg(werror
));
132 /****************************************************************************
133 ****************************************************************************/
135 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
140 printf("\tprintername:[%s]\n", r
->printername
);
141 printf("\tservername:[%s]\n", r
->servername
);
142 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
143 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
144 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
145 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
146 r
->time
.day
, r
->time
.day_of_week
);
147 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
148 r
->time
.second
, r
->time
.millisecond
);
150 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
151 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
153 printf("\tversion:[0x%x]\n", r
->version
);
154 printf("\tfree_build:[0x%x]\n", r
->free_build
);
155 printf("\tspooling:[0x%x]\n", r
->spooling
);
156 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
157 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
158 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
159 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
160 printf("\tjob_error:[0x%x]\n", r
->job_error
);
161 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
162 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
163 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
164 printf("\tchange_id:[0x%x]\n", r
->change_id
);
165 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
166 printf("\tstatus:[0x%x]\n", r
->status
);
167 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
168 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
169 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
170 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
171 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
172 printf("\treserved2:[0x%x]\n", r
->reserved2
);
173 printf("\treserved3:[0x%x]\n", r
->reserved3
);
178 /****************************************************************************
179 ****************************************************************************/
181 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
183 printf("\tflags:[0x%x]\n", r
->flags
);
184 printf("\tname:[%s]\n", r
->name
);
185 printf("\tdescription:[%s]\n", r
->description
);
186 printf("\tcomment:[%s]\n", r
->comment
);
191 /****************************************************************************
192 ****************************************************************************/
194 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
196 printf("\tservername:[%s]\n", r
->servername
);
197 printf("\tprintername:[%s]\n", r
->printername
);
198 printf("\tsharename:[%s]\n", r
->sharename
);
199 printf("\tportname:[%s]\n", r
->portname
);
200 printf("\tdrivername:[%s]\n", r
->drivername
);
201 printf("\tcomment:[%s]\n", r
->comment
);
202 printf("\tlocation:[%s]\n", r
->location
);
203 printf("\tsepfile:[%s]\n", r
->sepfile
);
204 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
205 printf("\tdatatype:[%s]\n", r
->datatype
);
206 printf("\tparameters:[%s]\n", r
->parameters
);
207 printf("\tattributes:[0x%x]\n", r
->attributes
);
208 printf("\tpriority:[0x%x]\n", r
->priority
);
209 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
210 printf("\tstarttime:[0x%x]\n", r
->starttime
);
211 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
212 printf("\tstatus:[0x%x]\n", r
->status
);
213 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
214 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
217 display_sec_desc(r
->secdesc
);
222 /****************************************************************************
223 ****************************************************************************/
225 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
227 display_sec_desc(r
->secdesc
);
232 /****************************************************************************
233 ****************************************************************************/
235 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
237 printf("\tservername:[%s]\n", r
->servername
);
238 printf("\tprintername:[%s]\n", r
->printername
);
239 printf("\tattributes:[0x%x]\n", r
->attributes
);
243 /****************************************************************************
244 ****************************************************************************/
246 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
248 printf("\tprintername:[%s]\n", r
->printername
);
249 printf("\tportname:[%s]\n", r
->portname
);
250 printf("\tattributes:[0x%x]\n", r
->attributes
);
251 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
252 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
256 /****************************************************************************
257 ****************************************************************************/
259 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
261 printf("\tstatus:[0x%x]\n", r
->status
);
265 /****************************************************************************
266 ****************************************************************************/
268 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
270 printf("\tguid:[%s]\n", r
->guid
);
271 printf("\taction:[0x%x]\n", r
->action
);
275 /****************************************************************************
276 ****************************************************************************/
278 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
280 int argc
, const char **argv
)
284 union spoolss_PrinterInfo
*info
;
287 uint32_t flags
= PRINTER_ENUM_LOCAL
;
290 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
295 level
= atoi(argv
[1]);
301 name
= cli
->srv_name_slash
;
305 flags
= atoi(argv
[3]);
308 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
315 if (W_ERROR_IS_OK(result
)) {
318 printf ("No printers returned.\n");
322 for (i
= 0; i
< count
; i
++) {
325 display_print_info0(&info
[i
].info0
);
328 display_print_info1(&info
[i
].info1
);
331 display_print_info2(&info
[i
].info2
);
334 display_print_info3(&info
[i
].info3
);
337 display_print_info4(&info
[i
].info4
);
340 display_print_info5(&info
[i
].info5
);
343 display_print_info6(&info
[i
].info6
);
346 printf("unknown info level %d\n", level
);
356 /****************************************************************************
357 ****************************************************************************/
359 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
361 printf("\tPort Name:\t[%s]\n", r
->port_name
);
364 /****************************************************************************
365 ****************************************************************************/
367 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
369 printf("\tPort Name:\t[%s]\n", r
->port_name
);
370 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
371 printf("\tDescription:\t[%s]\n", r
->description
);
372 printf("\tPort Type:\t" );
374 int comma
= 0; /* hack */
376 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
380 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
381 printf( "%sWrite", comma
? ", " : "" );
384 /* These two have slightly different interpretations
385 on 95/98/ME but I'm disregarding that for now */
386 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
387 printf( "%sRedirected", comma
? ", " : "" );
390 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
391 printf( "%sNet-Attached", comma
? ", " : "" );
395 printf( "[Unset]\n" );
397 printf("\tReserved:\t[%d]\n", r
->reserved
);
401 /****************************************************************************
402 ****************************************************************************/
404 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
405 TALLOC_CTX
*mem_ctx
, int argc
,
411 union spoolss_PortInfo
*info
;
414 printf("Usage: %s [level]\n", argv
[0]);
419 level
= atoi(argv
[1]);
422 /* Enumerate ports */
424 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
430 if (W_ERROR_IS_OK(result
)) {
433 for (i
= 0; i
< count
; i
++) {
436 display_port_info_1(&info
[i
].info1
);
439 display_port_info_2(&info
[i
].info2
);
442 printf("unknown info level %d\n", level
);
451 /****************************************************************************
452 ****************************************************************************/
454 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
456 int argc
, const char **argv
)
458 struct policy_handle pol
;
461 uint32_t info_level
= 2;
462 union spoolss_PrinterInfo info
;
463 struct spoolss_SetPrinterInfoCtr info_ctr
;
464 const char *printername
, *comment
= NULL
;
465 struct spoolss_DevmodeContainer devmode_ctr
;
466 struct sec_desc_buf secdesc_ctr
;
468 if (argc
== 1 || argc
> 3) {
469 printf("Usage: %s printername comment\n", argv
[0]);
474 /* Open a printer handle */
479 ZERO_STRUCT(devmode_ctr
);
480 ZERO_STRUCT(secdesc_ctr
);
482 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
484 /* get a printer handle */
485 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
489 if (!W_ERROR_IS_OK(result
))
492 /* Get printer info */
493 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
498 if (!W_ERROR_IS_OK(result
))
502 /* Modify the comment. */
503 info
.info2
.comment
= comment
;
504 info
.info2
.secdesc
= NULL
;
505 info
.info2
.devmode
= NULL
;
508 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
510 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
517 if (W_ERROR_IS_OK(result
))
518 printf("Success in setting comment.\n");
521 if (is_valid_policy_hnd(&pol
))
522 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
527 /****************************************************************************
528 ****************************************************************************/
530 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
532 int argc
, const char **argv
)
534 struct policy_handle pol
;
537 uint32_t info_level
= 2;
538 union spoolss_PrinterInfo info
;
539 const char *printername
,
540 *new_printername
= NULL
;
541 struct spoolss_SetPrinterInfoCtr info_ctr
;
542 struct spoolss_DevmodeContainer devmode_ctr
;
543 struct sec_desc_buf secdesc_ctr
;
545 ZERO_STRUCT(devmode_ctr
);
546 ZERO_STRUCT(secdesc_ctr
);
548 if (argc
== 1 || argc
> 3) {
549 printf("Usage: %s printername new_printername\n", argv
[0]);
554 /* Open a printer handle */
556 new_printername
= argv
[2];
559 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
561 /* get a printer handle */
562 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
566 if (!W_ERROR_IS_OK(result
))
569 /* Get printer info */
570 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
575 if (!W_ERROR_IS_OK(result
))
578 /* Modify the printername. */
579 info
.info2
.printername
= new_printername
;
580 info
.info2
.devmode
= NULL
;
581 info
.info2
.secdesc
= NULL
;
583 info_ctr
.level
= info_level
;
584 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
586 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
593 if (W_ERROR_IS_OK(result
))
594 printf("Success in setting printername.\n");
597 if (is_valid_policy_hnd(&pol
))
598 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
603 /****************************************************************************
604 ****************************************************************************/
606 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
608 int argc
, const char **argv
)
610 struct policy_handle pol
;
613 const char *printername
;
614 union spoolss_PrinterInfo info
;
616 if (argc
== 1 || argc
> 3) {
617 printf("Usage: %s <printername> [level]\n", argv
[0]);
621 /* Open a printer handle */
623 level
= atoi(argv
[2]);
626 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
628 /* get a printer handle */
630 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
632 SEC_FLAG_MAXIMUM_ALLOWED
,
634 if (!W_ERROR_IS_OK(result
)) {
638 /* Get printer info */
640 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
645 if (!W_ERROR_IS_OK(result
)) {
649 /* Display printer info */
652 display_print_info0(&info
.info0
);
655 display_print_info1(&info
.info1
);
658 display_print_info2(&info
.info2
);
661 display_print_info3(&info
.info3
);
664 display_print_info4(&info
.info4
);
667 display_print_info5(&info
.info5
);
670 display_print_info6(&info
.info6
);
673 display_print_info7(&info
.info7
);
676 printf("unknown info level %d\n", level
);
680 if (is_valid_policy_hnd(&pol
)) {
681 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
687 /****************************************************************************
688 ****************************************************************************/
690 static void display_reg_value(struct regval_blob value
)
692 const char *text
= NULL
;
697 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
698 *((uint32_t *) value
.data_p
));
701 blob
= data_blob_const(value
.data_p
, value
.size
);
702 pull_reg_sz(talloc_tos(), &blob
, &text
);
703 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
706 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
708 printf("%s: REG_BINARY:", value
.valuename
);
710 for (i
=0; i
<len
; i
++) {
711 if (hex
[i
] == '\0') {
726 blob
= data_blob_const(value
.data_p
, value
.size
);
728 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
729 d_printf("pull_reg_multi_sz failed\n");
733 printf("%s: REG_MULTI_SZ: \n", value
.valuename
);
734 for (i
=0; values
[i
] != NULL
; i
++) {
735 d_printf("%s\n", values
[i
]);
741 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
746 /****************************************************************************
747 ****************************************************************************/
749 static void display_printer_data(const char *v
,
750 enum winreg_Type type
,
751 union spoolss_PrinterData
*r
)
757 printf("%s: REG_DWORD: 0x%08x\n", v
, r
->value
);
760 printf("%s: REG_SZ: %s\n", v
, r
->string
);
763 char *hex
= hex_encode_talloc(NULL
,
764 r
->binary
.data
, r
->binary
.length
);
766 printf("%s: REG_BINARY:", v
);
768 for (i
=0; i
<len
; i
++) {
769 if (hex
[i
] == '\0') {
782 printf("%s: REG_MULTI_SZ: ", v
);
783 for (i
=0; r
->string_array
[i
] != NULL
; i
++) {
784 printf("%s ", r
->string_array
[i
]);
789 printf("%s: unknown type 0x%02x:\n", v
, type
);
794 /****************************************************************************
795 ****************************************************************************/
797 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
799 int argc
, const char **argv
)
801 struct policy_handle pol
;
804 const char *valuename
;
805 enum winreg_Type type
;
806 union spoolss_PrinterData data
;
809 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
810 printf("<printername> of . queries print server\n");
815 /* Open a printer handle */
817 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
818 fstrcpy(printername
, cli
->srv_name_slash
);
820 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
821 cli
->srv_name_slash
, argv
[1]);
823 /* get a printer handle */
825 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
827 SEC_FLAG_MAXIMUM_ALLOWED
,
829 if (!W_ERROR_IS_OK(result
))
832 /* Get printer info */
834 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
840 if (!W_ERROR_IS_OK(result
))
843 /* Display printer data */
845 display_printer_data(valuename
, type
, &data
);
848 if (is_valid_policy_hnd(&pol
))
849 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
854 /****************************************************************************
855 ****************************************************************************/
857 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
859 int argc
, const char **argv
)
861 struct policy_handle pol
;
865 const char *valuename
, *keyname
;
866 struct regval_blob value
;
868 enum winreg_Type type
;
869 uint8_t *buffer
= NULL
;
870 uint32_t offered
= 0;
874 printf("Usage: %s <printername> <keyname> <valuename>\n",
876 printf("<printername> of . queries print server\n");
882 /* Open a printer handle */
884 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
885 fstrcpy(printername
, cli
->srv_name_slash
);
887 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
888 cli
->srv_name_slash
, argv
[1]);
890 /* get a printer handle */
892 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
894 SEC_FLAG_MAXIMUM_ALLOWED
,
896 if (!W_ERROR_IS_OK(result
))
899 /* Get printer info */
901 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
910 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
912 buffer
= talloc_array(mem_ctx
, uint8_t, needed
);
913 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
924 if (!NT_STATUS_IS_OK(status
)) {
928 if (!W_ERROR_IS_OK(result
)) {
933 if (!W_ERROR_IS_OK(result
))
936 /* Display printer data */
938 fstrcpy(value
.valuename
, valuename
);
941 value
.data_p
= buffer
;
943 display_reg_value(value
);
946 if (is_valid_policy_hnd(&pol
))
947 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
952 /****************************************************************************
953 ****************************************************************************/
955 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
961 printf("Printer Driver Info 1:\n");
962 printf("\tDriver Name: [%s]\n", r
->driver_name
);
966 /****************************************************************************
967 ****************************************************************************/
969 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
975 printf("Printer Driver Info 2:\n");
976 printf("\tVersion: [%x]\n", r
->version
);
977 printf("\tDriver Name: [%s]\n", r
->driver_name
);
978 printf("\tArchitecture: [%s]\n", r
->architecture
);
979 printf("\tDriver Path: [%s]\n", r
->driver_path
);
980 printf("\tDatafile: [%s]\n", r
->data_file
);
981 printf("\tConfigfile: [%s]\n", r
->config_file
);
985 /****************************************************************************
986 ****************************************************************************/
988 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
996 printf("Printer Driver Info 3:\n");
997 printf("\tVersion: [%x]\n", r
->version
);
998 printf("\tDriver Name: [%s]\n", r
->driver_name
);
999 printf("\tArchitecture: [%s]\n", r
->architecture
);
1000 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1001 printf("\tDatafile: [%s]\n", r
->data_file
);
1002 printf("\tConfigfile: [%s]\n", r
->config_file
);
1003 printf("\tHelpfile: [%s]\n", r
->help_file
);
1005 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1006 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1009 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1010 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1014 /****************************************************************************
1015 ****************************************************************************/
1017 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1025 printf("Printer Driver Info 4:\n");
1026 printf("\tVersion: [%x]\n", r
->version
);
1027 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1028 printf("\tArchitecture: [%s]\n", r
->architecture
);
1029 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1030 printf("\tDatafile: [%s]\n", r
->data_file
);
1031 printf("\tConfigfile: [%s]\n", r
->config_file
);
1032 printf("\tHelpfile: [%s]\n", r
->help_file
);
1034 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1035 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1038 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1039 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1041 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1042 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1047 /****************************************************************************
1048 ****************************************************************************/
1050 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1056 printf("Printer Driver Info 5:\n");
1057 printf("\tVersion: [%x]\n", r
->version
);
1058 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1059 printf("\tArchitecture: [%s]\n", r
->architecture
);
1060 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1061 printf("\tDatafile: [%s]\n", r
->data_file
);
1062 printf("\tConfigfile: [%s]\n", r
->config_file
);
1063 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1064 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1065 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1069 /****************************************************************************
1070 ****************************************************************************/
1072 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1080 printf("Printer Driver Info 6:\n");
1081 printf("\tVersion: [%x]\n", r
->version
);
1082 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1083 printf("\tArchitecture: [%s]\n", r
->architecture
);
1084 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1085 printf("\tDatafile: [%s]\n", r
->data_file
);
1086 printf("\tConfigfile: [%s]\n", r
->config_file
);
1087 printf("\tHelpfile: [%s]\n", r
->help_file
);
1089 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1090 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1093 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1094 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1096 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1097 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1100 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1101 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1102 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1103 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1104 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1105 printf("\tProvider: [%s]\n", r
->provider
);
1110 /****************************************************************************
1111 ****************************************************************************/
1113 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1121 printf("Printer Driver Info 8:\n");
1122 printf("\tVersion: [%x]\n", r
->version
);
1123 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1124 printf("\tArchitecture: [%s]\n", r
->architecture
);
1125 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1126 printf("\tDatafile: [%s]\n", r
->data_file
);
1127 printf("\tConfigfile: [%s]\n", r
->config_file
);
1128 printf("\tHelpfile: [%s]\n", r
->help_file
);
1129 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1130 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1132 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1133 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1136 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1137 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1140 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1141 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1142 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1143 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1144 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1145 printf("\tProvider: [%s]\n", r
->provider
);
1146 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1147 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1148 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1149 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1151 printf("\tInf Path: [%s]\n", r
->inf_path
);
1152 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1153 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1154 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1156 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1157 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1158 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1163 /****************************************************************************
1164 ****************************************************************************/
1166 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1167 TALLOC_CTX
*mem_ctx
,
1168 int argc
, const char **argv
)
1170 struct policy_handle pol
;
1173 const char *printername
;
1175 bool success
= false;
1176 union spoolss_DriverInfo info
;
1177 uint32_t server_major_version
;
1178 uint32_t server_minor_version
;
1180 if ((argc
== 1) || (argc
> 3)) {
1181 printf("Usage: %s <printername> [level]\n", argv
[0]);
1185 /* get the arguments need to open the printer handle */
1187 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1190 level
= atoi(argv
[2]);
1193 /* Open a printer handle */
1195 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1199 if (!W_ERROR_IS_OK(werror
)) {
1200 printf("Error opening printer handle for %s!\n", printername
);
1204 /* loop through and print driver info level for each architecture */
1206 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1208 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1210 archi_table
[i
].long_archi
,
1213 archi_table
[i
].version
,
1216 &server_major_version
,
1217 &server_minor_version
);
1218 if (!W_ERROR_IS_OK(werror
)) {
1222 /* need at least one success */
1226 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1230 display_print_driver1(&info
.info1
);
1233 display_print_driver2(&info
.info2
);
1236 display_print_driver3(&info
.info3
);
1239 display_print_driver4(&info
.info4
);
1242 display_print_driver5(&info
.info5
);
1245 display_print_driver6(&info
.info6
);
1248 display_print_driver8(&info
.info8
);
1251 printf("unknown info level %d\n", level
);
1258 if (is_valid_policy_hnd(&pol
)) {
1259 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1269 /****************************************************************************
1270 ****************************************************************************/
1272 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1273 TALLOC_CTX
*mem_ctx
,
1274 const char *architecture
,
1279 union spoolss_DriverInfo
*info
= NULL
;
1282 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1283 cli
->srv_name_slash
,
1290 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1291 printf("Server does not support environment [%s]\n",
1300 if (!W_ERROR_IS_OK(werror
)) {
1301 printf("Error getting driver for environment [%s] - %s\n",
1302 architecture
, win_errstr(werror
));
1306 printf("\n[%s]\n", architecture
);
1310 for (j
=0; j
< count
; j
++) {
1311 display_print_driver1(&info
[j
].info1
);
1315 for (j
=0; j
< count
; j
++) {
1316 display_print_driver2(&info
[j
].info2
);
1320 for (j
=0; j
< count
; j
++) {
1321 display_print_driver3(&info
[j
].info3
);
1325 for (j
=0; j
< count
; j
++) {
1326 display_print_driver4(&info
[j
].info4
);
1330 for (j
=0; j
< count
; j
++) {
1331 display_print_driver5(&info
[j
].info5
);
1335 for (j
=0; j
< count
; j
++) {
1336 display_print_driver6(&info
[j
].info6
);
1340 for (j
=0; j
< count
; j
++) {
1341 display_print_driver8(&info
[j
].info8
);
1345 printf("unknown info level %d\n", level
);
1346 return WERR_UNKNOWN_LEVEL
;
1352 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1353 TALLOC_CTX
*mem_ctx
,
1354 int argc
, const char **argv
)
1356 WERROR werror
= WERR_OK
;
1359 const char *architecture
= NULL
;
1362 printf("Usage: enumdrivers [level] [architecture]\n");
1367 level
= atoi(argv
[1]);
1371 architecture
= argv
[2];
1375 return enum_driver_by_architecture(cli
, mem_ctx
,
1380 /* loop through and print driver info level for each architecture */
1381 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1382 /* check to see if we already asked for this architecture string */
1384 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1388 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1389 archi_table
[i
].long_archi
,
1391 if (!W_ERROR_IS_OK(werror
)) {
1399 /****************************************************************************
1400 ****************************************************************************/
1402 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1404 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1407 /****************************************************************************
1408 ****************************************************************************/
1410 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1411 TALLOC_CTX
*mem_ctx
,
1412 int argc
, const char **argv
)
1416 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1419 union spoolss_DriverDirectoryInfo info
;
1423 printf("Usage: %s [environment]\n", argv
[0]);
1427 /* Get the arguments need to open the printer handle */
1433 /* Get the directory. Only use Info level 1 */
1435 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1436 cli
->srv_name_slash
,
1444 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1446 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1448 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1449 cli
->srv_name_slash
,
1459 if (W_ERROR_IS_OK(result
)) {
1460 display_printdriverdir_1(&info
.info1
);
1466 /****************************************************************************
1467 ****************************************************************************/
1469 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1470 struct spoolss_AddDriverInfo3
*info
,
1476 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1478 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1480 info
->version
= archi_table
[i
].version
;
1481 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1486 if (archi_table
[i
].long_archi
== NULL
)
1488 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1495 /**************************************************************************
1496 wrapper for strtok to get the next parameter from a delimited list.
1497 Needed to handle the empty parameter string denoted by "NULL"
1498 *************************************************************************/
1500 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1501 const char *delim
, const char **dest
,
1506 /* get the next token */
1507 ptr
= strtok_r(str
, delim
, saveptr
);
1509 /* a string of 'NULL' is used to represent an empty
1510 parameter because two consecutive delimiters
1511 will not return an empty string. See man strtok(3)
1513 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1518 *dest
= talloc_strdup(mem_ctx
, ptr
);
1524 /********************************************************************************
1525 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1526 string in the form of
1527 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1528 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1529 <Default Data Type>:<Comma Separated list of Files>
1530 *******************************************************************************/
1532 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1537 char *saveptr
= NULL
;
1538 struct spoolss_StringArray
*deps
;
1539 const char **file_array
= NULL
;
1542 /* fill in the UNISTR fields */
1543 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1544 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1545 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1546 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1547 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1548 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1549 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1551 /* <Comma Separated List of Dependent Files> */
1552 /* save the beginning of the string */
1553 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1556 /* begin to strip out each filename */
1557 str
= strtok_r(str
, ",", &saveptr
);
1559 /* no dependent files, we are done */
1564 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1569 while (str
!= NULL
) {
1570 add_string_to_array(deps
, str
, &file_array
, &count
);
1571 str
= strtok_r(NULL
, ",", &saveptr
);
1574 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1575 if (!deps
->string
) {
1579 for (i
=0; i
< count
; i
++) {
1580 deps
->string
[i
] = file_array
[i
];
1583 r
->dependent_files
= deps
;
1588 /****************************************************************************
1589 ****************************************************************************/
1591 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1592 TALLOC_CTX
*mem_ctx
,
1593 int argc
, const char **argv
)
1598 struct spoolss_AddDriverInfoCtr info_ctr
;
1599 struct spoolss_AddDriverInfo3 info3
;
1603 /* parse the command arguments */
1604 if (argc
!= 3 && argc
!= 4)
1606 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1607 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1608 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1609 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1610 printf ("\t[version]\n");
1615 /* Fill in the spoolss_AddDriverInfo3 struct */
1618 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1620 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1621 return WERR_INVALID_PARAM
;
1624 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1626 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1627 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1629 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1630 return WERR_INVALID_PARAM
;
1633 /* if printer driver version specified, override the default version
1634 * used by the architecture. This allows installation of Windows
1635 * 2000 (version 3) printer drivers. */
1638 info3
.version
= atoi(argv
[3]);
1642 info_ctr
.level
= level
;
1643 info_ctr
.info
.info3
= &info3
;
1645 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1646 cli
->srv_name_slash
,
1649 if (!NT_STATUS_IS_OK(status
)) {
1650 return ntstatus_to_werror(status
);
1652 if (W_ERROR_IS_OK(result
)) {
1653 printf ("Printer Driver %s successfully installed.\n",
1661 /****************************************************************************
1662 ****************************************************************************/
1664 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1665 TALLOC_CTX
*mem_ctx
,
1666 int argc
, const char **argv
)
1669 struct spoolss_SetPrinterInfoCtr info_ctr
;
1670 struct spoolss_SetPrinterInfo2 info2
;
1672 /* parse the command arguments */
1675 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1679 /* Fill in the DRIVER_INFO_2 struct */
1682 info2
.printername
= argv
[1];
1683 info2
.drivername
= argv
[3];
1684 info2
.sharename
= argv
[2];
1685 info2
.portname
= argv
[4];
1686 info2
.comment
= "Created by rpcclient";
1687 info2
.printprocessor
= "winprint";
1688 info2
.datatype
= "RAW";
1689 info2
.devmode
= NULL
;
1690 info2
.secdesc
= NULL
;
1691 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1693 info2
.defaultpriority
= 0;
1694 info2
.starttime
= 0;
1695 info2
.untiltime
= 0;
1697 /* These three fields must not be used by AddPrinter()
1698 as defined in the MS Platform SDK documentation..
1702 info2.averageppm = 0;
1706 info_ctr
.info
.info2
= &info2
;
1708 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1710 if (W_ERROR_IS_OK(result
))
1711 printf ("Printer %s successfully installed.\n", argv
[1]);
1716 /****************************************************************************
1717 ****************************************************************************/
1719 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1720 TALLOC_CTX
*mem_ctx
,
1721 int argc
, const char **argv
)
1723 struct policy_handle pol
;
1727 const char *printername
;
1728 union spoolss_PrinterInfo info
;
1729 struct spoolss_SetPrinterInfoCtr info_ctr
;
1730 struct spoolss_DevmodeContainer devmode_ctr
;
1731 struct sec_desc_buf secdesc_ctr
;
1733 ZERO_STRUCT(devmode_ctr
);
1734 ZERO_STRUCT(secdesc_ctr
);
1736 /* parse the command arguments */
1739 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1743 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1745 /* Get a printer handle */
1747 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1751 if (!W_ERROR_IS_OK(result
))
1754 /* Get printer info */
1756 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1761 if (!W_ERROR_IS_OK(result
)) {
1762 printf ("Unable to retrieve printer information!\n");
1766 /* Set the printer driver */
1768 info
.info2
.drivername
= argv
[2];
1769 info
.info2
.devmode
= NULL
;
1770 info
.info2
.secdesc
= NULL
;
1773 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
1775 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1782 if (!W_ERROR_IS_OK(result
)) {
1783 printf("SetPrinter call failed!\n");
1787 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1792 if (is_valid_policy_hnd(&pol
))
1793 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1799 /****************************************************************************
1800 ****************************************************************************/
1802 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1803 TALLOC_CTX
*mem_ctx
,
1804 int argc
, const char **argv
)
1806 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1812 const char *arch
= NULL
;
1813 uint32_t delete_flags
= 0;
1815 /* parse the command arguments */
1816 if (argc
< 2 || argc
> 4) {
1817 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1824 vers
= atoi (argv
[3]);
1827 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1830 /* delete the driver for all architectures */
1831 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1833 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1836 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1839 /* make the call to remove the driver */
1840 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1841 cli
->srv_name_slash
,
1842 archi_table
[i
].long_archi
,
1845 archi_table
[i
].version
,
1848 if ( !W_ERROR_IS_OK(result
) )
1850 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1851 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1852 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1857 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1858 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1867 /****************************************************************************
1868 ****************************************************************************/
1870 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1871 TALLOC_CTX
*mem_ctx
,
1872 int argc
, const char **argv
)
1874 WERROR result
= WERR_OK
;
1878 /* parse the command arguments */
1880 printf ("Usage: %s <driver>\n", argv
[0]);
1884 /* delete the driver for all architectures */
1885 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1886 /* make the call to remove the driver */
1887 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1888 cli
->srv_name_slash
,
1889 archi_table
[i
].long_archi
,
1892 if (!NT_STATUS_IS_OK(status
)) {
1895 if ( !W_ERROR_IS_OK(result
) ) {
1896 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1897 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1898 argv
[1], archi_table
[i
].long_archi
,
1902 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1903 archi_table
[i
].long_archi
);
1910 /****************************************************************************
1911 ****************************************************************************/
1913 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1914 TALLOC_CTX
*mem_ctx
,
1915 int argc
, const char **argv
)
1919 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1922 union spoolss_PrintProcessorDirectoryInfo info
;
1925 /* parse the command arguments */
1927 printf ("Usage: %s [environment]\n", argv
[0]);
1932 environment
= argv
[1];
1935 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1936 cli
->srv_name_slash
,
1944 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1946 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1948 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1949 cli
->srv_name_slash
,
1959 if (W_ERROR_IS_OK(result
)) {
1960 printf("%s\n", info
.info1
.directory_name
);
1966 /****************************************************************************
1967 ****************************************************************************/
1969 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1970 int argc
, const char **argv
)
1972 struct policy_handle handle
;
1975 const char *printername
;
1976 union spoolss_AddFormInfo info
;
1977 struct spoolss_AddFormInfo1 info1
;
1978 struct spoolss_AddFormInfo2 info2
;
1981 /* Parse the command arguments */
1983 if (argc
< 3 || argc
> 5) {
1984 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
1988 /* Get a printer handle */
1990 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1992 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1996 if (!W_ERROR_IS_OK(werror
))
1999 /* Dummy up some values for the form data */
2002 level
= atoi(argv
[3]);
2007 info1
.flags
= SPOOLSS_FORM_USER
;
2008 info1
.form_name
= argv
[2];
2009 info1
.size
.width
= 100;
2010 info1
.size
.height
= 100;
2011 info1
.area
.left
= 0;
2012 info1
.area
.top
= 10;
2013 info1
.area
.right
= 20;
2014 info1
.area
.bottom
= 30;
2016 info
.info1
= &info1
;
2020 info2
.flags
= SPOOLSS_FORM_USER
;
2021 info2
.form_name
= argv
[2];
2022 info2
.size
.width
= 100;
2023 info2
.size
.height
= 100;
2024 info2
.area
.left
= 0;
2025 info2
.area
.top
= 10;
2026 info2
.area
.right
= 20;
2027 info2
.area
.bottom
= 30;
2028 info2
.keyword
= argv
[2];
2029 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2030 info2
.mui_dll
= NULL
;
2031 info2
.ressource_id
= 0;
2032 info2
.display_name
= argv
[2];
2035 info
.info2
= &info2
;
2043 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
2050 if (is_valid_policy_hnd(&handle
))
2051 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2056 /****************************************************************************
2057 ****************************************************************************/
2059 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2060 int argc
, const char **argv
)
2062 struct policy_handle handle
;
2065 const char *printername
;
2066 union spoolss_AddFormInfo info
;
2067 struct spoolss_AddFormInfo1 info1
;
2069 /* Parse the command arguments */
2072 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2076 /* Get a printer handle */
2078 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2080 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2082 SEC_FLAG_MAXIMUM_ALLOWED
,
2084 if (!W_ERROR_IS_OK(werror
))
2087 /* Dummy up some values for the form data */
2089 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2090 info1
.size
.width
= 100;
2091 info1
.size
.height
= 100;
2092 info1
.area
.left
= 0;
2093 info1
.area
.top
= 1000;
2094 info1
.area
.right
= 2000;
2095 info1
.area
.bottom
= 3000;
2096 info1
.form_name
= argv
[2];
2098 info
.info1
= &info1
;
2102 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
2110 if (is_valid_policy_hnd(&handle
))
2111 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2116 /****************************************************************************
2117 ****************************************************************************/
2119 static const char *get_form_flag(int form_flag
)
2121 switch (form_flag
) {
2122 case SPOOLSS_FORM_USER
:
2124 case SPOOLSS_FORM_BUILTIN
:
2125 return "FORM_BUILTIN";
2126 case SPOOLSS_FORM_PRINTER
:
2127 return "FORM_PRINTER";
2133 /****************************************************************************
2134 ****************************************************************************/
2136 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2139 "\tflag: %s (%d)\n" \
2140 "\twidth: %d, length: %d\n" \
2141 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2142 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2143 r
->size
.width
, r
->size
.height
,
2144 r
->area
.left
, r
->area
.right
,
2145 r
->area
.top
, r
->area
.bottom
);
2148 /****************************************************************************
2149 ****************************************************************************/
2151 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2154 "\tflag: %s (%d)\n" \
2155 "\twidth: %d, length: %d\n" \
2156 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2157 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2158 r
->size
.width
, r
->size
.height
,
2159 r
->area
.left
, r
->area
.right
,
2160 r
->area
.top
, r
->area
.bottom
);
2161 printf("\tkeyword: %s\n", r
->keyword
);
2162 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2163 printf("\tmui_dll: %s\n", r
->mui_dll
);
2164 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2165 printf("\tdisplay_name: %s\n", r
->display_name
);
2166 printf("\tlang_id: %d\n", r
->lang_id
);
2170 /****************************************************************************
2171 ****************************************************************************/
2173 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2174 int argc
, const char **argv
)
2176 struct policy_handle handle
;
2179 const char *printername
;
2181 uint32_t offered
= 0;
2182 union spoolss_FormInfo info
;
2186 /* Parse the command arguments */
2188 if (argc
< 3 || argc
> 5) {
2189 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2193 /* Get a printer handle */
2195 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2197 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2199 SEC_FLAG_MAXIMUM_ALLOWED
,
2201 if (!W_ERROR_IS_OK(werror
))
2205 level
= atoi(argv
[3]);
2210 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2219 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2220 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2222 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2233 if (!NT_STATUS_IS_OK(status
)) {
2239 display_form_info1(&info
.info1
);
2242 display_form_info2(&info
.info2
);
2247 if (is_valid_policy_hnd(&handle
))
2248 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2253 /****************************************************************************
2254 ****************************************************************************/
2256 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2257 TALLOC_CTX
*mem_ctx
, int argc
,
2260 struct policy_handle handle
;
2263 const char *printername
;
2265 /* Parse the command arguments */
2268 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2272 /* Get a printer handle */
2274 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2276 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2278 SEC_FLAG_MAXIMUM_ALLOWED
,
2280 if (!W_ERROR_IS_OK(werror
))
2283 /* Delete the form */
2285 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2289 if (!NT_STATUS_IS_OK(status
)) {
2290 return ntstatus_to_werror(status
);
2294 if (is_valid_policy_hnd(&handle
))
2295 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2300 /****************************************************************************
2301 ****************************************************************************/
2303 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2304 TALLOC_CTX
*mem_ctx
, int argc
,
2307 struct policy_handle handle
;
2309 const char *printername
;
2310 uint32_t num_forms
, level
= 1, i
;
2311 union spoolss_FormInfo
*forms
;
2313 /* Parse the command arguments */
2315 if (argc
< 2 || argc
> 4) {
2316 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2320 /* Get a printer handle */
2322 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2324 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2326 SEC_FLAG_MAXIMUM_ALLOWED
,
2328 if (!W_ERROR_IS_OK(werror
))
2332 level
= atoi(argv
[2]);
2335 /* Enumerate forms */
2337 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2344 if (!W_ERROR_IS_OK(werror
))
2347 /* Display output */
2349 for (i
= 0; i
< num_forms
; i
++) {
2352 display_form_info1(&forms
[i
].info1
);
2355 display_form_info2(&forms
[i
].info2
);
2361 if (is_valid_policy_hnd(&handle
))
2362 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2367 /****************************************************************************
2368 ****************************************************************************/
2370 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2371 TALLOC_CTX
*mem_ctx
,
2372 int argc
, const char **argv
)
2376 const char *printername
;
2377 struct policy_handle pol
;
2378 union spoolss_PrinterInfo info
;
2379 enum winreg_Type type
;
2380 union spoolss_PrinterData data
;
2382 /* parse the command arguments */
2384 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2385 " <value> <data>\n",
2387 result
= WERR_INVALID_PARAM
;
2391 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2395 if (strequal(argv
[2], "string")) {
2399 if (strequal(argv
[2], "binary")) {
2403 if (strequal(argv
[2], "dword")) {
2407 if (strequal(argv
[2], "multistring")) {
2408 type
= REG_MULTI_SZ
;
2411 if (type
== REG_NONE
) {
2412 printf("Unknown data type: %s\n", argv
[2]);
2413 result
= WERR_INVALID_PARAM
;
2417 /* get a printer handle */
2419 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2421 SEC_FLAG_MAXIMUM_ALLOWED
,
2423 if (!W_ERROR_IS_OK(result
)) {
2427 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2432 if (!W_ERROR_IS_OK(result
)) {
2436 printf("%s\n", current_timestring(mem_ctx
, true));
2437 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2439 /* Set the printer data */
2443 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2444 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2447 data
.value
= strtoul(argv
[4], NULL
, 10);
2450 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2452 case REG_MULTI_SZ
: {
2454 const char **strings
= NULL
;
2456 for (i
=4; i
<argc
; i
++) {
2457 if (strcmp(argv
[i
], "NULL") == 0) {
2460 if (!add_string_to_array(mem_ctx
, argv
[i
],
2463 result
= WERR_NOMEM
;
2467 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2468 if (!data
.string_array
) {
2469 result
= WERR_NOMEM
;
2472 for (i
=0; i
< num_strings
; i
++) {
2473 data
.string_array
[i
] = strings
[i
];
2478 printf("Unknown data type: %s\n", argv
[2]);
2479 result
= WERR_INVALID_PARAM
;
2483 status
= rpccli_spoolss_SetPrinterData(cli
, mem_ctx
,
2485 argv
[3], /* value_name */
2488 0, /* autocalculated size */
2490 if (!W_ERROR_IS_OK(result
)) {
2491 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2494 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2496 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2501 if (!W_ERROR_IS_OK(result
)) {
2505 printf("%s\n", current_timestring(mem_ctx
, true));
2506 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2510 if (is_valid_policy_hnd(&pol
)) {
2511 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2517 /****************************************************************************
2518 ****************************************************************************/
2520 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2522 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2523 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2527 /****************************************************************************
2528 ****************************************************************************/
2530 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2532 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2533 r
->position
, r
->job_id
,
2534 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2535 r
->total_pages
, r
->size
);
2538 /****************************************************************************
2539 ****************************************************************************/
2541 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2543 printf("jobid[%d], next_jobid[%d]\n",
2544 r
->job_id
, r
->next_job_id
);
2547 /****************************************************************************
2548 ****************************************************************************/
2550 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2552 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2553 r
->position
, r
->job_id
,
2554 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2555 r
->total_pages
, r
->size
, r
->size_high
);
2558 /****************************************************************************
2559 ****************************************************************************/
2561 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2562 TALLOC_CTX
*mem_ctx
, int argc
,
2566 uint32_t level
= 1, count
, i
;
2567 const char *printername
;
2568 struct policy_handle hnd
;
2569 union spoolss_JobInfo
*info
;
2571 if (argc
< 2 || argc
> 3) {
2572 printf("Usage: %s printername [level]\n", argv
[0]);
2577 level
= atoi(argv
[2]);
2580 /* Open printer handle */
2582 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2584 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2586 SEC_FLAG_MAXIMUM_ALLOWED
,
2588 if (!W_ERROR_IS_OK(result
))
2591 /* Enumerate ports */
2593 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2601 if (!W_ERROR_IS_OK(result
)) {
2605 for (i
= 0; i
< count
; i
++) {
2608 display_job_info1(&info
[i
].info1
);
2611 display_job_info2(&info
[i
].info2
);
2614 d_printf("unknown info level %d\n", level
);
2620 if (is_valid_policy_hnd(&hnd
)) {
2621 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2627 /****************************************************************************
2628 ****************************************************************************/
2630 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2631 TALLOC_CTX
*mem_ctx
, int argc
,
2635 const char *printername
;
2636 struct policy_handle hnd
;
2639 union spoolss_JobInfo info
;
2641 if (argc
< 3 || argc
> 4) {
2642 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2646 job_id
= atoi(argv
[2]);
2649 level
= atoi(argv
[3]);
2652 /* Open printer handle */
2654 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2656 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2658 SEC_FLAG_MAXIMUM_ALLOWED
,
2660 if (!W_ERROR_IS_OK(result
)) {
2664 /* Enumerate ports */
2666 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2673 if (!W_ERROR_IS_OK(result
)) {
2679 display_job_info1(&info
.info1
);
2682 display_job_info2(&info
.info2
);
2685 display_job_info3(&info
.info3
);
2688 display_job_info4(&info
.info4
);
2691 d_printf("unknown info level %d\n", level
);
2696 if (is_valid_policy_hnd(&hnd
)) {
2697 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2703 /****************************************************************************
2704 ****************************************************************************/
2706 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2707 TALLOC_CTX
*mem_ctx
, int argc
,
2712 const char *printername
;
2713 struct policy_handle hnd
;
2715 enum spoolss_JobControl command
;
2718 printf("Usage: %s printername job_id command\n", argv
[0]);
2722 job_id
= atoi(argv
[2]);
2723 command
= atoi(argv
[3]);
2725 /* Open printer handle */
2727 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2729 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2731 SEC_FLAG_MAXIMUM_ALLOWED
,
2733 if (!W_ERROR_IS_OK(result
)) {
2739 status
= rpccli_spoolss_SetJob(cli
, mem_ctx
,
2746 if (!W_ERROR_IS_OK(result
)) {
2751 if (is_valid_policy_hnd(&hnd
)) {
2752 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2758 /****************************************************************************
2759 ****************************************************************************/
2761 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2762 TALLOC_CTX
*mem_ctx
, int argc
,
2768 const char *printername
;
2769 struct policy_handle hnd
;
2770 uint32_t value_offered
= 0;
2771 const char *value_name
= NULL
;
2772 uint32_t value_needed
;
2773 enum winreg_Type type
;
2774 uint8_t *data
= NULL
;
2775 uint32_t data_offered
= 0;
2776 uint32_t data_needed
;
2779 printf("Usage: %s printername\n", argv
[0]);
2783 /* Open printer handle */
2785 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2787 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2789 SEC_FLAG_MAXIMUM_ALLOWED
,
2791 if (!W_ERROR_IS_OK(result
)) {
2795 /* Enumerate data */
2797 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2809 data_offered
= data_needed
;
2810 value_offered
= value_needed
;
2811 data
= talloc_zero_array(mem_ctx
, uint8_t, data_needed
);
2812 value_name
= talloc_zero_array(mem_ctx
, char, value_needed
);
2814 while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2816 status
= rpccli_spoolss_EnumPrinterData(cli
, mem_ctx
,
2827 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
2828 struct regval_blob v
;
2829 fstrcpy(v
.valuename
, value_name
);
2831 v
.size
= data_offered
;
2833 display_reg_value(v
);
2837 if (W_ERROR_V(result
) == ERRnomoreitems
) {
2838 result
= W_ERROR(ERRsuccess
);
2842 if (is_valid_policy_hnd(&hnd
)) {
2843 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2849 /****************************************************************************
2850 ****************************************************************************/
2852 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2853 TALLOC_CTX
*mem_ctx
, int argc
,
2858 const char *printername
;
2859 struct policy_handle hnd
;
2861 struct spoolss_PrinterEnumValues
*info
;
2864 printf("Usage: %s printername <keyname>\n", argv
[0]);
2868 /* Open printer handle */
2870 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2872 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2874 SEC_FLAG_MAXIMUM_ALLOWED
,
2876 if (!W_ERROR_IS_OK(result
)) {
2880 /* Enumerate subkeys */
2882 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
2888 if (!W_ERROR_IS_OK(result
)) {
2892 for (i
=0; i
< count
; i
++) {
2893 display_printer_data(info
[i
].value_name
,
2899 if (is_valid_policy_hnd(&hnd
)) {
2900 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2906 /****************************************************************************
2907 ****************************************************************************/
2909 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
2910 TALLOC_CTX
*mem_ctx
, int argc
,
2914 const char *printername
;
2915 const char *keyname
= NULL
;
2916 struct policy_handle hnd
;
2917 const char **key_buffer
= NULL
;
2920 if (argc
< 2 || argc
> 3) {
2921 printf("Usage: %s printername [keyname]\n", argv
[0]);
2931 /* Open printer handle */
2933 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2935 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2937 SEC_FLAG_MAXIMUM_ALLOWED
,
2939 if (!W_ERROR_IS_OK(result
)) {
2943 /* Enumerate subkeys */
2945 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
2951 if (!W_ERROR_IS_OK(result
)) {
2955 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
2956 printf("%s\n", key_buffer
[i
]);
2961 if (is_valid_policy_hnd(&hnd
)) {
2962 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2968 /****************************************************************************
2969 ****************************************************************************/
2971 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2972 TALLOC_CTX
*mem_ctx
, int argc
,
2975 const char *printername
;
2976 const char *clientname
;
2977 struct policy_handle hnd
;
2980 struct spoolss_NotifyOption option
;
2983 printf("Usage: %s printername\n", argv
[0]);
2990 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2992 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2994 SEC_FLAG_MAXIMUM_ALLOWED
,
2996 if (!W_ERROR_IS_OK(result
)) {
2997 printf("Error opening %s\n", argv
[1]);
3001 /* Create spool options */
3006 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3007 if (option
.types
== NULL
) {
3008 result
= WERR_NOMEM
;
3012 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3013 option
.types
[0].count
= 1;
3014 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3015 if (option
.types
[0].fields
== NULL
) {
3016 result
= WERR_NOMEM
;
3019 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3021 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3022 option
.types
[1].count
= 1;
3023 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3024 if (option
.types
[1].fields
== NULL
) {
3025 result
= WERR_NOMEM
;
3028 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3030 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
3032 result
= WERR_NOMEM
;
3038 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
3046 if (!W_ERROR_IS_OK(result
)) {
3047 printf("Error rffpcnex %s\n", argv
[1]);
3052 if (is_valid_policy_hnd(&hnd
))
3053 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
3058 /****************************************************************************
3059 ****************************************************************************/
3061 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3062 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3064 union spoolss_PrinterInfo info1
, info2
;
3066 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3068 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3069 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3074 if ( !W_ERROR_IS_OK(werror
) ) {
3075 printf("failed (%s)\n", win_errstr(werror
));
3076 talloc_destroy(mem_ctx
);
3081 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3082 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3087 if ( !W_ERROR_IS_OK(werror
) ) {
3088 printf("failed (%s)\n", win_errstr(werror
));
3089 talloc_destroy(mem_ctx
);
3094 talloc_destroy(mem_ctx
);
3099 /****************************************************************************
3100 ****************************************************************************/
3102 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3103 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3105 union spoolss_PrinterInfo info1
, info2
;
3107 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3108 SEC_DESC
*sd1
, *sd2
;
3112 printf("Retrieving printer security for %s...", cli1
->desthost
);
3113 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3118 if ( !W_ERROR_IS_OK(werror
) ) {
3119 printf("failed (%s)\n", win_errstr(werror
));
3125 printf("Retrieving printer security for %s...", cli2
->desthost
);
3126 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3131 if ( !W_ERROR_IS_OK(werror
) ) {
3132 printf("failed (%s)\n", win_errstr(werror
));
3141 sd1
= info1
.info3
.secdesc
;
3142 sd2
= info2
.info3
.secdesc
;
3144 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3145 printf("NULL secdesc!\n");
3150 if (!security_descriptor_equal( sd1
, sd2
) ) {
3151 printf("Security Descriptors *not* equal!\n");
3156 printf("Security descriptors match\n");
3159 talloc_destroy(mem_ctx
);
3164 /****************************************************************************
3165 ****************************************************************************/
3167 extern struct user_auth_info
*rpcclient_auth_info
;
3169 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3170 TALLOC_CTX
*mem_ctx
, int argc
,
3173 const char *printername
;
3174 char *printername_path
= NULL
;
3175 struct cli_state
*cli_server2
= NULL
;
3176 struct rpc_pipe_client
*cli2
= NULL
;
3177 struct policy_handle hPrinter1
, hPrinter2
;
3182 printf("Usage: %s <printer> <server>\n", argv
[0]);
3186 printername
= argv
[1];
3188 /* first get the connection to the remote server */
3190 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
3193 get_cmdline_auth_info_username(rpcclient_auth_info
),
3195 get_cmdline_auth_info_password(rpcclient_auth_info
),
3196 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3197 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
3199 if ( !NT_STATUS_IS_OK(nt_status
) )
3200 return WERR_GENERAL_FAILURE
;
3202 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
.syntax_id
,
3204 if (!NT_STATUS_IS_OK(nt_status
)) {
3205 printf("failed to open spoolss pipe on server %s (%s)\n",
3206 argv
[2], nt_errstr(nt_status
));
3207 return WERR_GENERAL_FAILURE
;
3210 /* now open up both printers */
3212 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3214 printf("Opening %s...", printername_path
);
3216 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3220 if ( !W_ERROR_IS_OK(werror
) ) {
3221 printf("failed (%s)\n", win_errstr(werror
));
3226 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3228 printf("Opening %s...", printername_path
);
3229 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3233 if ( !W_ERROR_IS_OK(werror
) ) {
3234 printf("failed (%s)\n", win_errstr(werror
));
3239 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3240 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3242 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3249 printf("Closing printers...");
3250 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3251 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3254 /* close the second remote connection */
3256 cli_shutdown( cli_server2
);
3260 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3262 printf("print_processor_name: %s\n", r
->print_processor_name
);
3265 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3266 TALLOC_CTX
*mem_ctx
, int argc
,
3270 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3271 uint32_t num_procs
, level
= 1, i
;
3272 union spoolss_PrintProcessorInfo
*procs
;
3274 /* Parse the command arguments */
3276 if (argc
< 1 || argc
> 4) {
3277 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3282 environment
= argv
[1];
3286 level
= atoi(argv
[2]);
3289 /* Enumerate Print Processors */
3291 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3292 cli
->srv_name_slash
,
3298 if (!W_ERROR_IS_OK(werror
))
3301 /* Display output */
3303 for (i
= 0; i
< num_procs
; i
++) {
3306 display_proc_info1(&procs
[i
].info1
);
3315 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3317 printf("name_array: %s\n", r
->name_array
);
3320 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3321 TALLOC_CTX
*mem_ctx
, int argc
,
3325 const char *print_processor_name
= "winprint";
3326 uint32_t num_procs
, level
= 1, i
;
3327 union spoolss_PrintProcDataTypesInfo
*procs
;
3329 /* Parse the command arguments */
3331 if (argc
< 1 || argc
> 4) {
3332 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3337 print_processor_name
= argv
[1];
3341 level
= atoi(argv
[2]);
3344 /* Enumerate Print Processor Data Types */
3346 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3347 cli
->srv_name_slash
,
3348 print_processor_name
,
3353 if (!W_ERROR_IS_OK(werror
))
3356 /* Display output */
3358 for (i
= 0; i
< num_procs
; i
++) {
3361 display_proc_data_types_info1(&procs
[i
].info1
);
3370 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3372 printf("monitor_name: %s\n", r
->monitor_name
);
3375 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3377 printf("monitor_name: %s\n", r
->monitor_name
);
3378 printf("environment: %s\n", r
->environment
);
3379 printf("dll_name: %s\n", r
->dll_name
);
3382 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3383 TALLOC_CTX
*mem_ctx
, int argc
,
3387 uint32_t count
, level
= 1, i
;
3388 union spoolss_MonitorInfo
*info
;
3390 /* Parse the command arguments */
3393 printf("Usage: %s [level]\n", argv
[0]);
3398 level
= atoi(argv
[1]);
3401 /* Enumerate Print Monitors */
3403 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3404 cli
->srv_name_slash
,
3409 if (!W_ERROR_IS_OK(werror
)) {
3413 /* Display output */
3415 for (i
= 0; i
< count
; i
++) {
3418 display_monitor1(&info
[i
].info1
);
3421 display_monitor2(&info
[i
].info2
);
3430 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3431 TALLOC_CTX
*mem_ctx
, int argc
,
3436 struct policy_handle handle
, gdi_handle
;
3437 const char *printername
;
3438 struct spoolss_DevmodeContainer devmode_ctr
;
3440 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3442 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3444 SEC_FLAG_MAXIMUM_ALLOWED
,
3446 if (!W_ERROR_IS_OK(result
)) {
3450 ZERO_STRUCT(devmode_ctr
);
3452 status
= rpccli_spoolss_CreatePrinterIC(cli
, mem_ctx
,
3457 if (!W_ERROR_IS_OK(result
)) {
3462 if (is_valid_policy_hnd(&gdi_handle
)) {
3463 rpccli_spoolss_DeletePrinterIC(cli
, mem_ctx
, &gdi_handle
, NULL
);
3465 if (is_valid_policy_hnd(&handle
)) {
3466 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
3472 /* List of commands exported by this module */
3473 struct cmd_set spoolss_commands
[] = {
3477 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a print driver", "" },
3478 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add a printer", "" },
3479 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver", "" },
3480 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete a printer driver with files", "" },
3481 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data", "" },
3482 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer data for a key", "" },
3483 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer keys", "" },
3484 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate print jobs", "" },
3485 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print job", "" },
3486 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set print job", "" },
3487 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printer ports", "" },
3488 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate installed printer drivers", "" },
3489 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate printers", "" },
3490 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver data", "" },
3491 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer driver data with keyname", ""},
3492 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver information", "" },
3493 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print driver upload directory", "" },
3494 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get printer info", "" },
3495 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Open printer handle", "" },
3496 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer driver", "" },
3497 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get print processor directory", "" },
3498 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Add form", "" },
3499 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set form", "" },
3500 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Get form", "" },
3501 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
.syntax_id
, NULL
, "Delete form", "" },
3502 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate forms", "" },
3503 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printer comment", "" },
3504 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set printername", "" },
3505 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
.syntax_id
, NULL
, "Set REG_SZ printer data", "" },
3506 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
.syntax_id
, NULL
, "Rffpcnex test", "" },
3507 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
.syntax_id
, NULL
, "Printer comparison test", "" },
3508 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processors", "" },
3509 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Processor Data Types", "" },
3510 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
.syntax_id
, NULL
, "Enumerate Print Monitors", "" },
3511 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
.syntax_id
, NULL
, "Create Printer IC", "" },