2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "rpcclient.h"
27 #include "../librpc/gen_ndr/cli_spoolss.h"
28 #include "rpc_client/cli_spoolss.h"
29 #include "rpc_client/init_spoolss.h"
31 #include "registry/reg_objects.h"
32 #include "nt_printing.h"
34 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
36 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
37 _cli->srv_name_slash, _arg); \
38 W_ERROR_HAVE_NO_MEMORY(_printername); \
41 /* The version int is used by getdrivers. Note that
42 all architecture strings that support mutliple
43 versions must be grouped together since enumdrivers
44 uses this property to prevent issuing multiple
45 enumdriver calls for the same arch */
48 static const struct print_architecture_table_node archi_table[]= {
50 {"Windows 4.0", "WIN40", 0 },
51 {"Windows NT x86", "W32X86", 2 },
52 {"Windows NT x86", "W32X86", 3 },
53 {"Windows NT R4000", "W32MIPS", 2 },
54 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
55 {"Windows NT PowerPC", "W32PPC", 2 },
56 {"Windows IA64", "IA64", 3 },
57 {"Windows x64", "x64", 3 },
64 * rpcclient module for SPOOLSS rpc pipe.
66 * This generally just parses and checks command lines, and then calls
67 * a cli_spoolss function.
70 /****************************************************************************
71 function to do the mapping between the long architecture name and
73 ****************************************************************************/
75 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
79 DEBUG(107,("Getting architecture dependant directory\n"));
82 } while ( (archi_table[i].long_archi!=NULL ) &&
83 StrCaseCmp(long_archi, archi_table[i].long_archi) );
85 if (archi_table[i].long_archi==NULL) {
86 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
90 /* this might be client code - but shouldn't this be an fstrcpy etc? */
93 DEBUGADD(108,("index: [%d]\n", i));
94 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
95 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
97 return archi_table[i].short_archi;
100 /****************************************************************************
101 ****************************************************************************/
103 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
105 int argc, const char **argv)
108 struct policy_handle hnd;
109 uint32_t access_mask = PRINTER_ALL_ACCESS;
112 printf("Usage: %s <printername> [access_mask]\n", argv[0]);
117 sscanf(argv[2], "%x", &access_mask);
120 /* Open the printer handle */
122 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
126 if (W_ERROR_IS_OK(werror)) {
127 printf("Printer %s opened successfully\n", argv[1]);
128 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
130 if (!W_ERROR_IS_OK(werror)) {
131 printf("Error closing printer handle! (%s)\n",
132 get_dos_error_msg(werror));
139 /****************************************************************************
140 ****************************************************************************/
142 static WERROR cmd_spoolss_open_printer(struct rpc_pipe_client *cli,
144 int argc, const char **argv)
147 struct policy_handle hnd;
148 uint32_t access_mask = PRINTER_ALL_ACCESS;
150 struct spoolss_DevmodeContainer devmode_ctr;
152 ZERO_STRUCT(devmode_ctr);
155 printf("Usage: %s <printername> [access_mask]\n", argv[0]);
160 sscanf(argv[2], "%x", &access_mask);
163 /* Open the printer handle */
165 status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
172 if (W_ERROR_IS_OK(werror)) {
173 printf("Printer %s opened successfully\n", argv[1]);
174 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
176 if (!W_ERROR_IS_OK(werror)) {
177 printf("Error closing printer handle! (%s)\n",
178 get_dos_error_msg(werror));
185 /****************************************************************************
186 ****************************************************************************/
188 static void display_print_info0(struct spoolss_PrinterInfo0 *r)
193 printf("\tprintername:[%s]\n", r->printername);
194 printf("\tservername:[%s]\n", r->servername);
195 printf("\tcjobs:[0x%x]\n", r->cjobs);
196 printf("\ttotal_jobs:[0x%x]\n", r->total_jobs);
197 printf("\ttotal_bytes:[0x%x]\n", r->total_bytes);
198 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month,
199 r->time.day, r->time.day_of_week);
200 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute,
201 r->time.second, r->time.millisecond);
203 printf("\tglobal_counter:[0x%x]\n", r->global_counter);
204 printf("\ttotal_pages:[0x%x]\n", r->total_pages);
206 printf("\tversion:[0x%x]\n", r->version);
207 printf("\tfree_build:[0x%x]\n", r->free_build);
208 printf("\tspooling:[0x%x]\n", r->spooling);
209 printf("\tmax_spooling:[0x%x]\n", r->max_spooling);
210 printf("\tsession_counter:[0x%x]\n", r->session_counter);
211 printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper);
212 printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready);
213 printf("\tjob_error:[0x%x]\n", r->job_error);
214 printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors);
215 printf("\tprocessor_type:[0x%x]\n", r->processor_type);
216 printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes);
217 printf("\tchange_id:[0x%x]\n", r->change_id);
218 printf("\tlast_error: %s\n", win_errstr(r->last_error));
219 printf("\tstatus:[0x%x]\n", r->status);
220 printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers);
221 printf("\tc_setprinter:[0x%x]\n", r->c_setprinter);
222 printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture);
223 printf("\tprocessor_level:[0x%x]\n", r->processor_level);
224 printf("\tref_ic:[0x%x]\n", r->ref_ic);
225 printf("\treserved2:[0x%x]\n", r->reserved2);
226 printf("\treserved3:[0x%x]\n", r->reserved3);
231 /****************************************************************************
232 ****************************************************************************/
234 static void display_print_info1(struct spoolss_PrinterInfo1 *r)
236 printf("\tflags:[0x%x]\n", r->flags);
237 printf("\tname:[%s]\n", r->name);
238 printf("\tdescription:[%s]\n", r->description);
239 printf("\tcomment:[%s]\n", r->comment);
244 /****************************************************************************
245 ****************************************************************************/
247 static void display_print_info2(struct spoolss_PrinterInfo2 *r)
249 printf("\tservername:[%s]\n", r->servername);
250 printf("\tprintername:[%s]\n", r->printername);
251 printf("\tsharename:[%s]\n", r->sharename);
252 printf("\tportname:[%s]\n", r->portname);
253 printf("\tdrivername:[%s]\n", r->drivername);
254 printf("\tcomment:[%s]\n", r->comment);
255 printf("\tlocation:[%s]\n", r->location);
256 printf("\tsepfile:[%s]\n", r->sepfile);
257 printf("\tprintprocessor:[%s]\n", r->printprocessor);
258 printf("\tdatatype:[%s]\n", r->datatype);
259 printf("\tparameters:[%s]\n", r->parameters);
260 printf("\tattributes:[0x%x]\n", r->attributes);
261 printf("\tpriority:[0x%x]\n", r->priority);
262 printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority);
263 printf("\tstarttime:[0x%x]\n", r->starttime);
264 printf("\tuntiltime:[0x%x]\n", r->untiltime);
265 printf("\tstatus:[0x%x]\n", r->status);
266 printf("\tcjobs:[0x%x]\n", r->cjobs);
267 printf("\taverageppm:[0x%x]\n", r->averageppm);
270 display_sec_desc(r->secdesc);
275 /****************************************************************************
276 ****************************************************************************/
278 static void display_print_info3(struct spoolss_PrinterInfo3 *r)
280 display_sec_desc(r->secdesc);
285 /****************************************************************************
286 ****************************************************************************/
288 static void display_print_info4(struct spoolss_PrinterInfo4 *r)
290 printf("\tservername:[%s]\n", r->servername);
291 printf("\tprintername:[%s]\n", r->printername);
292 printf("\tattributes:[0x%x]\n", r->attributes);
296 /****************************************************************************
297 ****************************************************************************/
299 static void display_print_info5(struct spoolss_PrinterInfo5 *r)
301 printf("\tprintername:[%s]\n", r->printername);
302 printf("\tportname:[%s]\n", r->portname);
303 printf("\tattributes:[0x%x]\n", r->attributes);
304 printf("\tdevice_not_selected_timeout:[0x%x]\n", r->device_not_selected_timeout);
305 printf("\ttransmission_retry_timeout:[0x%x]\n", r->transmission_retry_timeout);
309 /****************************************************************************
310 ****************************************************************************/
312 static void display_print_info6(struct spoolss_PrinterInfo6 *r)
314 printf("\tstatus:[0x%x]\n", r->status);
318 /****************************************************************************
319 ****************************************************************************/
321 static void display_print_info7(struct spoolss_PrinterInfo7 *r)
323 printf("\tguid:[%s]\n", r->guid);
324 printf("\taction:[0x%x]\n", r->action);
328 /****************************************************************************
329 ****************************************************************************/
331 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
333 int argc, const char **argv)
337 union spoolss_PrinterInfo *info;
340 uint32_t flags = PRINTER_ENUM_LOCAL;
343 printf("Usage: %s [level] [name] [flags]\n", argv[0]);
348 level = atoi(argv[1]);
354 name = cli->srv_name_slash;
358 flags = atoi(argv[3]);
361 result = rpccli_spoolss_enumprinters(cli, mem_ctx,
368 if (W_ERROR_IS_OK(result)) {
371 printf ("No printers returned.\n");
375 for (i = 0; i < count; i++) {
378 display_print_info0(&info[i].info0);
381 display_print_info1(&info[i].info1);
384 display_print_info2(&info[i].info2);
387 display_print_info3(&info[i].info3);
390 display_print_info4(&info[i].info4);
393 display_print_info5(&info[i].info5);
396 display_print_info6(&info[i].info6);
399 printf("unknown info level %d\n", level);
409 /****************************************************************************
410 ****************************************************************************/
412 static void display_port_info_1(struct spoolss_PortInfo1 *r)
414 printf("\tPort Name:\t[%s]\n", r->port_name);
417 /****************************************************************************
418 ****************************************************************************/
420 static void display_port_info_2(struct spoolss_PortInfo2 *r)
422 printf("\tPort Name:\t[%s]\n", r->port_name);
423 printf("\tMonitor Name:\t[%s]\n", r->monitor_name);
424 printf("\tDescription:\t[%s]\n", r->description);
425 printf("\tPort Type:\t" );
427 int comma = 0; /* hack */
429 if (r->port_type & SPOOLSS_PORT_TYPE_READ) {
433 if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) {
434 printf( "%sWrite", comma ? ", " : "" );
437 /* These two have slightly different interpretations
438 on 95/98/ME but I'm disregarding that for now */
439 if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) {
440 printf( "%sRedirected", comma ? ", " : "" );
443 if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) {
444 printf( "%sNet-Attached", comma ? ", " : "" );
448 printf( "[Unset]\n" );
450 printf("\tReserved:\t[%d]\n", r->reserved);
454 /****************************************************************************
455 ****************************************************************************/
457 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
458 TALLOC_CTX *mem_ctx, int argc,
464 union spoolss_PortInfo *info;
467 printf("Usage: %s [level]\n", argv[0]);
472 level = atoi(argv[1]);
475 /* Enumerate ports */
477 result = rpccli_spoolss_enumports(cli, mem_ctx,
483 if (W_ERROR_IS_OK(result)) {
486 for (i = 0; i < count; i++) {
489 display_port_info_1(&info[i].info1);
492 display_port_info_2(&info[i].info2);
495 printf("unknown info level %d\n", level);
504 /****************************************************************************
505 ****************************************************************************/
507 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
509 int argc, const char **argv)
511 struct policy_handle pol;
514 uint32_t info_level = 2;
515 union spoolss_PrinterInfo info;
516 struct spoolss_SetPrinterInfoCtr info_ctr;
517 struct spoolss_SetPrinterInfo2 info2;
518 const char *printername, *comment = NULL;
519 struct spoolss_DevmodeContainer devmode_ctr;
520 struct sec_desc_buf secdesc_ctr;
522 if (argc == 1 || argc > 3) {
523 printf("Usage: %s printername comment\n", argv[0]);
528 /* Open a printer handle */
533 ZERO_STRUCT(devmode_ctr);
534 ZERO_STRUCT(secdesc_ctr);
536 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
538 /* get a printer handle */
539 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
543 if (!W_ERROR_IS_OK(result))
546 /* Get printer info */
547 result = rpccli_spoolss_getprinter(cli, mem_ctx,
552 if (!W_ERROR_IS_OK(result))
556 /* Modify the comment. */
557 spoolss_printerinfo2_to_setprinterinfo2(&info.info2, &info2);
558 info2.comment = comment;
561 info_ctr.info.info2 = &info2;
563 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
570 if (W_ERROR_IS_OK(result))
571 printf("Success in setting comment.\n");
574 if (is_valid_policy_hnd(&pol))
575 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
580 /****************************************************************************
581 ****************************************************************************/
583 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
585 int argc, const char **argv)
587 struct policy_handle pol;
590 uint32_t info_level = 2;
591 union spoolss_PrinterInfo info;
592 const char *printername,
593 *new_printername = NULL;
594 struct spoolss_SetPrinterInfoCtr info_ctr;
595 struct spoolss_SetPrinterInfo2 info2;
596 struct spoolss_DevmodeContainer devmode_ctr;
597 struct sec_desc_buf secdesc_ctr;
599 ZERO_STRUCT(devmode_ctr);
600 ZERO_STRUCT(secdesc_ctr);
602 if (argc == 1 || argc > 3) {
603 printf("Usage: %s printername new_printername\n", argv[0]);
608 /* Open a printer handle */
610 new_printername = argv[2];
613 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
615 /* get a printer handle */
616 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
620 if (!W_ERROR_IS_OK(result))
623 /* Get printer info */
624 result = rpccli_spoolss_getprinter(cli, mem_ctx,
629 if (!W_ERROR_IS_OK(result))
632 /* Modify the printername. */
633 spoolss_printerinfo2_to_setprinterinfo2(&info.info2, &info2);
634 info2.printername = new_printername;
637 info_ctr.info.info2 = &info2;
639 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
646 if (W_ERROR_IS_OK(result))
647 printf("Success in setting printername.\n");
650 if (is_valid_policy_hnd(&pol))
651 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
656 /****************************************************************************
657 ****************************************************************************/
659 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
661 int argc, const char **argv)
663 struct policy_handle pol;
666 const char *printername;
667 union spoolss_PrinterInfo info;
669 if (argc == 1 || argc > 3) {
670 printf("Usage: %s <printername> [level]\n", argv[0]);
674 /* Open a printer handle */
676 level = atoi(argv[2]);
679 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
681 /* get a printer handle */
683 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
685 SEC_FLAG_MAXIMUM_ALLOWED,
687 if (!W_ERROR_IS_OK(result)) {
691 /* Get printer info */
693 result = rpccli_spoolss_getprinter(cli, mem_ctx,
698 if (!W_ERROR_IS_OK(result)) {
702 /* Display printer info */
705 display_print_info0(&info.info0);
708 display_print_info1(&info.info1);
711 display_print_info2(&info.info2);
714 display_print_info3(&info.info3);
717 display_print_info4(&info.info4);
720 display_print_info5(&info.info5);
723 display_print_info6(&info.info6);
726 display_print_info7(&info.info7);
729 printf("unknown info level %d\n", level);
733 if (is_valid_policy_hnd(&pol)) {
734 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
740 /****************************************************************************
741 ****************************************************************************/
743 static void display_reg_value(struct regval_blob *value)
745 const char *text = NULL;
748 switch(regval_type(value)) {
750 printf("%s: REG_DWORD: 0x%08x\n", regval_name(value),
751 *((uint32_t *) regval_data_p(value)));
754 blob = data_blob_const(regval_data_p(value), regval_size(value));
755 pull_reg_sz(talloc_tos(), &blob, &text);
756 printf("%s: REG_SZ: %s\n", regval_name(value), text ? text : "");
759 char *hex = hex_encode_talloc(NULL, regval_data_p(value), regval_size(value));
761 printf("%s: REG_BINARY:", regval_name(value));
763 for (i=0; i<len; i++) {
764 if (hex[i] == '\0') {
779 blob = data_blob_const(regval_data_p(value), regval_size(value));
781 if (!pull_reg_multi_sz(NULL, &blob, &values)) {
782 d_printf("pull_reg_multi_sz failed\n");
786 printf("%s: REG_MULTI_SZ: \n", regval_name(value));
787 for (i=0; values[i] != NULL; i++) {
788 d_printf("%s\n", values[i]);
794 printf("%s: unknown type %d\n", regval_name(value), regval_type(value));
799 /****************************************************************************
800 ****************************************************************************/
802 static void display_printer_data(const char *v,
803 enum winreg_Type type,
808 union spoolss_PrinterData r;
809 DATA_BLOB blob = data_blob_const(data, length);
812 result = pull_spoolss_PrinterData(talloc_tos(), &blob, &r, type);
813 if (!W_ERROR_IS_OK(result)) {
819 printf("%s: REG_DWORD: 0x%08x\n", v, r.value);
822 printf("%s: REG_SZ: %s\n", v, r.string);
825 char *hex = hex_encode_talloc(NULL,
826 r.binary.data, r.binary.length);
828 printf("%s: REG_BINARY:", v);
830 for (i=0; i<len; i++) {
831 if (hex[i] == '\0') {
844 printf("%s: REG_MULTI_SZ: ", v);
845 for (i=0; r.string_array[i] != NULL; i++) {
846 printf("%s ", r.string_array[i]);
851 printf("%s: unknown type 0x%02x:\n", v, type);
856 /****************************************************************************
857 ****************************************************************************/
859 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
861 int argc, const char **argv)
863 struct policy_handle pol;
866 const char *valuename;
867 enum winreg_Type type;
872 printf("Usage: %s <printername> <valuename>\n", argv[0]);
873 printf("<printername> of . queries print server\n");
878 /* Open a printer handle */
880 if (strncmp(argv[1], ".", sizeof(".")) == 0)
881 fstrcpy(printername, cli->srv_name_slash);
883 slprintf(printername, sizeof(printername)-1, "%s\\%s",
884 cli->srv_name_slash, argv[1]);
886 /* get a printer handle */
888 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
890 SEC_FLAG_MAXIMUM_ALLOWED,
892 if (!W_ERROR_IS_OK(result))
895 /* Get printer info */
897 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
904 if (!W_ERROR_IS_OK(result))
907 /* Display printer data */
909 display_printer_data(valuename, type, data, needed);
912 if (is_valid_policy_hnd(&pol))
913 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
918 /****************************************************************************
919 ****************************************************************************/
921 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
923 int argc, const char **argv)
925 struct policy_handle pol;
929 const char *valuename, *keyname;
931 enum winreg_Type type;
932 uint8_t *data = NULL;
933 uint32_t offered = 0;
937 printf("Usage: %s <printername> <keyname> <valuename>\n",
939 printf("<printername> of . queries print server\n");
945 /* Open a printer handle */
947 if (strncmp(argv[1], ".", sizeof(".")) == 0)
948 fstrcpy(printername, cli->srv_name_slash);
950 slprintf(printername, sizeof(printername)-1, "%s\\%s",
951 cli->srv_name_slash, argv[1]);
953 /* get a printer handle */
955 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
957 SEC_FLAG_MAXIMUM_ALLOWED,
959 if (!W_ERROR_IS_OK(result))
962 /* Get printer info */
964 data = talloc_zero_array(mem_ctx, uint8_t, offered);
969 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
978 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
980 data = talloc_zero_array(mem_ctx, uint8_t, offered);
984 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
995 if (!NT_STATUS_IS_OK(status)) {
999 if (!W_ERROR_IS_OK(result))
1002 /* Display printer data */
1004 display_printer_data(valuename, type, data, needed);
1008 if (is_valid_policy_hnd(&pol))
1009 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1014 /****************************************************************************
1015 ****************************************************************************/
1017 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
1023 printf("Printer Driver Info 1:\n");
1024 printf("\tDriver Name: [%s]\n", r->driver_name);
1028 /****************************************************************************
1029 ****************************************************************************/
1031 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
1037 printf("Printer Driver Info 2:\n");
1038 printf("\tVersion: [%x]\n", r->version);
1039 printf("\tDriver Name: [%s]\n", r->driver_name);
1040 printf("\tArchitecture: [%s]\n", r->architecture);
1041 printf("\tDriver Path: [%s]\n", r->driver_path);
1042 printf("\tDatafile: [%s]\n", r->data_file);
1043 printf("\tConfigfile: [%s]\n", r->config_file);
1047 /****************************************************************************
1048 ****************************************************************************/
1050 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1058 printf("Printer Driver Info 3:\n");
1059 printf("\tVersion: [%x]\n", r->version);
1060 printf("\tDriver Name: [%s]\n", r->driver_name);
1061 printf("\tArchitecture: [%s]\n", r->architecture);
1062 printf("\tDriver Path: [%s]\n", r->driver_path);
1063 printf("\tDatafile: [%s]\n", r->data_file);
1064 printf("\tConfigfile: [%s]\n", r->config_file);
1065 printf("\tHelpfile: [%s]\n", r->help_file);
1067 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1068 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1071 printf("\tMonitorname: [%s]\n", r->monitor_name);
1072 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1076 /****************************************************************************
1077 ****************************************************************************/
1079 static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1087 printf("Printer Driver Info 4:\n");
1088 printf("\tVersion: [%x]\n", r->version);
1089 printf("\tDriver Name: [%s]\n", r->driver_name);
1090 printf("\tArchitecture: [%s]\n", r->architecture);
1091 printf("\tDriver Path: [%s]\n", r->driver_path);
1092 printf("\tDatafile: [%s]\n", r->data_file);
1093 printf("\tConfigfile: [%s]\n", r->config_file);
1094 printf("\tHelpfile: [%s]\n", r->help_file);
1096 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1097 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1100 printf("\tMonitorname: [%s]\n", r->monitor_name);
1101 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1103 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1104 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1109 /****************************************************************************
1110 ****************************************************************************/
1112 static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1118 printf("Printer Driver Info 5:\n");
1119 printf("\tVersion: [%x]\n", r->version);
1120 printf("\tDriver Name: [%s]\n", r->driver_name);
1121 printf("\tArchitecture: [%s]\n", r->architecture);
1122 printf("\tDriver Path: [%s]\n", r->driver_path);
1123 printf("\tDatafile: [%s]\n", r->data_file);
1124 printf("\tConfigfile: [%s]\n", r->config_file);
1125 printf("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1126 printf("\tConfig Version: [0x%x]\n", r->config_version);
1127 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1131 /****************************************************************************
1132 ****************************************************************************/
1134 static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1142 printf("Printer Driver Info 6:\n");
1143 printf("\tVersion: [%x]\n", r->version);
1144 printf("\tDriver Name: [%s]\n", r->driver_name);
1145 printf("\tArchitecture: [%s]\n", r->architecture);
1146 printf("\tDriver Path: [%s]\n", r->driver_path);
1147 printf("\tDatafile: [%s]\n", r->data_file);
1148 printf("\tConfigfile: [%s]\n", r->config_file);
1149 printf("\tHelpfile: [%s]\n", r->help_file);
1151 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1152 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1155 printf("\tMonitorname: [%s]\n", r->monitor_name);
1156 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1158 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1159 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1162 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1163 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1164 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1165 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1166 printf("\tHardware ID: [%s]\n", r->hardware_id);
1167 printf("\tProvider: [%s]\n", r->provider);
1172 /****************************************************************************
1173 ****************************************************************************/
1175 static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1183 printf("Printer Driver Info 8:\n");
1184 printf("\tVersion: [%x]\n", r->version);
1185 printf("\tDriver Name: [%s]\n", r->driver_name);
1186 printf("\tArchitecture: [%s]\n", r->architecture);
1187 printf("\tDriver Path: [%s]\n", r->driver_path);
1188 printf("\tDatafile: [%s]\n", r->data_file);
1189 printf("\tConfigfile: [%s]\n", r->config_file);
1190 printf("\tHelpfile: [%s]\n", r->help_file);
1191 printf("\tMonitorname: [%s]\n", r->monitor_name);
1192 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1194 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1195 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1198 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1199 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1202 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1203 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1204 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1205 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1206 printf("\tHardware ID: [%s]\n", r->hardware_id);
1207 printf("\tProvider: [%s]\n", r->provider);
1208 printf("\tPrint Processor: [%s]\n", r->print_processor);
1209 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1210 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1211 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1213 printf("\tInf Path: [%s]\n", r->inf_path);
1214 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1215 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1216 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1218 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1219 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1220 (long long unsigned int)r->min_inbox_driver_ver_version);
1225 /****************************************************************************
1226 ****************************************************************************/
1228 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1229 TALLOC_CTX *mem_ctx,
1230 int argc, const char **argv)
1232 struct policy_handle pol;
1235 const char *printername;
1237 bool success = false;
1238 union spoolss_DriverInfo info;
1239 uint32_t server_major_version;
1240 uint32_t server_minor_version;
1242 if ((argc == 1) || (argc > 3)) {
1243 printf("Usage: %s <printername> [level]\n", argv[0]);
1247 /* get the arguments need to open the printer handle */
1249 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1252 level = atoi(argv[2]);
1255 /* Open a printer handle */
1257 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1261 if (!W_ERROR_IS_OK(werror)) {
1262 printf("Error opening printer handle for %s!\n", printername);
1266 /* loop through and print driver info level for each architecture */
1268 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1270 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1272 archi_table[i].long_archi,
1275 archi_table[i].version,
1278 &server_major_version,
1279 &server_minor_version);
1280 if (!W_ERROR_IS_OK(werror)) {
1284 /* need at least one success */
1288 printf("\n[%s]\n", archi_table[i].long_archi);
1292 display_print_driver1(&info.info1);
1295 display_print_driver2(&info.info2);
1298 display_print_driver3(&info.info3);
1301 display_print_driver4(&info.info4);
1304 display_print_driver5(&info.info5);
1307 display_print_driver6(&info.info6);
1310 display_print_driver8(&info.info8);
1313 printf("unknown info level %d\n", level);
1320 if (is_valid_policy_hnd(&pol)) {
1321 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1331 /****************************************************************************
1332 ****************************************************************************/
1334 static WERROR enum_driver_by_architecture(struct rpc_pipe_client *cli,
1335 TALLOC_CTX *mem_ctx,
1336 const char *architecture,
1341 union spoolss_DriverInfo *info = NULL;
1344 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1345 cli->srv_name_slash,
1352 if (W_ERROR_EQUAL(werror, WERR_INVALID_ENVIRONMENT)) {
1353 printf("Server does not support environment [%s]\n",
1362 if (!W_ERROR_IS_OK(werror)) {
1363 printf("Error getting driver for environment [%s] - %s\n",
1364 architecture, win_errstr(werror));
1368 printf("\n[%s]\n", architecture);
1372 for (j=0; j < count; j++) {
1373 display_print_driver1(&info[j].info1);
1377 for (j=0; j < count; j++) {
1378 display_print_driver2(&info[j].info2);
1382 for (j=0; j < count; j++) {
1383 display_print_driver3(&info[j].info3);
1387 for (j=0; j < count; j++) {
1388 display_print_driver4(&info[j].info4);
1392 for (j=0; j < count; j++) {
1393 display_print_driver5(&info[j].info5);
1397 for (j=0; j < count; j++) {
1398 display_print_driver6(&info[j].info6);
1402 for (j=0; j < count; j++) {
1403 display_print_driver8(&info[j].info8);
1407 printf("unknown info level %d\n", level);
1408 return WERR_UNKNOWN_LEVEL;
1414 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1415 TALLOC_CTX *mem_ctx,
1416 int argc, const char **argv)
1418 WERROR werror = WERR_OK;
1421 const char *architecture = NULL;
1424 printf("Usage: enumdrivers [level] [architecture]\n");
1429 level = atoi(argv[1]);
1433 architecture = argv[2];
1437 return enum_driver_by_architecture(cli, mem_ctx,
1442 /* loop through and print driver info level for each architecture */
1443 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1444 /* check to see if we already asked for this architecture string */
1446 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1450 werror = enum_driver_by_architecture(cli, mem_ctx,
1451 archi_table[i].long_archi,
1453 if (!W_ERROR_IS_OK(werror)) {
1461 /****************************************************************************
1462 ****************************************************************************/
1464 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1466 printf("\tDirectory Name:[%s]\n", r->directory_name);
1469 /****************************************************************************
1470 ****************************************************************************/
1472 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1473 TALLOC_CTX *mem_ctx,
1474 int argc, const char **argv)
1478 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1481 union spoolss_DriverDirectoryInfo info;
1485 printf("Usage: %s [environment]\n", argv[0]);
1489 /* Get the arguments need to open the printer handle */
1495 /* Get the directory. Only use Info level 1 */
1497 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1498 cli->srv_name_slash,
1506 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1508 buffer = data_blob_talloc_zero(mem_ctx, needed);
1510 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1511 cli->srv_name_slash,
1521 if (W_ERROR_IS_OK(result)) {
1522 display_printdriverdir_1(&info.info1);
1528 /****************************************************************************
1529 ****************************************************************************/
1531 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1532 struct spoolss_AddDriverInfo3 *info,
1538 for (i=0; archi_table[i].long_archi != NULL; i++)
1540 if (strcmp(arch, archi_table[i].short_archi) == 0)
1542 info->version = archi_table[i].version;
1543 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1548 if (archi_table[i].long_archi == NULL)
1550 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1557 /**************************************************************************
1558 wrapper for strtok to get the next parameter from a delimited list.
1559 Needed to handle the empty parameter string denoted by "NULL"
1560 *************************************************************************/
1562 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1563 const char *delim, const char **dest,
1568 /* get the next token */
1569 ptr = strtok_r(str, delim, saveptr);
1571 /* a string of 'NULL' is used to represent an empty
1572 parameter because two consecutive delimiters
1573 will not return an empty string. See man strtok(3)
1575 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1580 *dest = talloc_strdup(mem_ctx, ptr);
1586 /********************************************************************************
1587 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1588 string in the form of
1589 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1590 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1591 <Default Data Type>:<Comma Separated list of Files>
1592 *******************************************************************************/
1594 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1599 char *saveptr = NULL;
1600 struct spoolss_StringArray *deps;
1601 const char **file_array = NULL;
1604 /* fill in the UNISTR fields */
1605 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1606 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1607 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1608 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1609 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1610 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1611 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1613 /* <Comma Separated List of Dependent Files> */
1614 /* save the beginning of the string */
1615 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1618 /* begin to strip out each filename */
1619 str = strtok_r(str, ",", &saveptr);
1621 /* no dependent files, we are done */
1626 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1631 while (str != NULL) {
1632 add_string_to_array(deps, str, &file_array, &count);
1633 str = strtok_r(NULL, ",", &saveptr);
1636 deps->string = talloc_zero_array(deps, const char *, count + 1);
1637 if (!deps->string) {
1641 for (i=0; i < count; i++) {
1642 deps->string[i] = file_array[i];
1645 r->dependent_files = deps;
1650 /****************************************************************************
1651 ****************************************************************************/
1653 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1654 TALLOC_CTX *mem_ctx,
1655 int argc, const char **argv)
1660 struct spoolss_AddDriverInfoCtr info_ctr;
1661 struct spoolss_AddDriverInfo3 info3;
1665 /* parse the command arguments */
1666 if (argc != 3 && argc != 4)
1668 printf ("Usage: %s <Environment> \\\n", argv[0]);
1669 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1670 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1671 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1672 printf ("\t[version]\n");
1677 /* Fill in the spoolss_AddDriverInfo3 struct */
1680 arch = cmd_spoolss_get_short_archi(argv[1]);
1682 printf ("Error Unknown architechture [%s]\n", argv[1]);
1683 return WERR_INVALID_PARAM;
1686 set_drv_info_3_env(mem_ctx, &info3, arch);
1688 driver_args = talloc_strdup( mem_ctx, argv[2] );
1689 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1691 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1692 return WERR_INVALID_PARAM;
1695 /* if printer driver version specified, override the default version
1696 * used by the architecture. This allows installation of Windows
1697 * 2000 (version 3) printer drivers. */
1700 info3.version = atoi(argv[3]);
1704 info_ctr.level = level;
1705 info_ctr.info.info3 = &info3;
1707 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1708 cli->srv_name_slash,
1711 if (!NT_STATUS_IS_OK(status)) {
1712 return ntstatus_to_werror(status);
1714 if (W_ERROR_IS_OK(result)) {
1715 printf ("Printer Driver %s successfully installed.\n",
1723 /****************************************************************************
1724 ****************************************************************************/
1726 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1727 TALLOC_CTX *mem_ctx,
1728 int argc, const char **argv)
1731 struct spoolss_SetPrinterInfoCtr info_ctr;
1732 struct spoolss_SetPrinterInfo2 info2;
1734 /* parse the command arguments */
1737 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1741 /* Fill in the DRIVER_INFO_2 struct */
1744 info2.printername = argv[1];
1745 info2.drivername = argv[3];
1746 info2.sharename = argv[2];
1747 info2.portname = argv[4];
1748 info2.comment = "Created by rpcclient";
1749 info2.printprocessor = "winprint";
1750 info2.datatype = "RAW";
1751 info2.devmode_ptr = 0;
1752 info2.secdesc_ptr = 0;
1753 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1755 info2.defaultpriority = 0;
1756 info2.starttime = 0;
1757 info2.untiltime = 0;
1759 /* These three fields must not be used by AddPrinter()
1760 as defined in the MS Platform SDK documentation..
1764 info2.averageppm = 0;
1768 info_ctr.info.info2 = &info2;
1770 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1772 if (W_ERROR_IS_OK(result))
1773 printf ("Printer %s successfully installed.\n", argv[1]);
1778 /****************************************************************************
1779 ****************************************************************************/
1781 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1782 TALLOC_CTX *mem_ctx,
1783 int argc, const char **argv)
1785 struct policy_handle pol;
1789 const char *printername;
1790 union spoolss_PrinterInfo info;
1791 struct spoolss_SetPrinterInfoCtr info_ctr;
1792 struct spoolss_SetPrinterInfo2 info2;
1793 struct spoolss_DevmodeContainer devmode_ctr;
1794 struct sec_desc_buf secdesc_ctr;
1796 ZERO_STRUCT(devmode_ctr);
1797 ZERO_STRUCT(secdesc_ctr);
1799 /* parse the command arguments */
1802 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1806 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1808 /* Get a printer handle */
1810 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1814 if (!W_ERROR_IS_OK(result))
1817 /* Get printer info */
1819 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1824 if (!W_ERROR_IS_OK(result)) {
1825 printf ("Unable to retrieve printer information!\n");
1829 /* Set the printer driver */
1831 spoolss_printerinfo2_to_setprinterinfo2(&info.info2, &info2);
1832 info2.drivername = argv[2];
1835 info_ctr.info.info2 = &info2;
1837 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1844 if (!W_ERROR_IS_OK(result)) {
1845 printf("SetPrinter call failed!\n");
1849 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1854 if (is_valid_policy_hnd(&pol))
1855 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1861 /****************************************************************************
1862 ****************************************************************************/
1864 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1865 TALLOC_CTX *mem_ctx,
1866 int argc, const char **argv)
1868 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1874 const char *arch = NULL;
1875 uint32_t delete_flags = 0;
1877 /* parse the command arguments */
1878 if (argc < 2 || argc > 4) {
1879 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1886 vers = atoi (argv[3]);
1889 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1892 /* delete the driver for all architectures */
1893 for (i=0; archi_table[i].long_archi; i++) {
1895 if (arch && !strequal( archi_table[i].long_archi, arch))
1898 if (vers >= 0 && archi_table[i].version != vers)
1901 /* make the call to remove the driver */
1902 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1903 cli->srv_name_slash,
1904 archi_table[i].long_archi,
1907 archi_table[i].version,
1910 if ( !W_ERROR_IS_OK(result) )
1912 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1913 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1914 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1919 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1920 archi_table[i].long_archi, archi_table[i].version);
1929 /****************************************************************************
1930 ****************************************************************************/
1932 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1933 TALLOC_CTX *mem_ctx,
1934 int argc, const char **argv)
1936 WERROR result = WERR_OK;
1940 /* parse the command arguments */
1942 printf ("Usage: %s <driver>\n", argv[0]);
1946 /* delete the driver for all architectures */
1947 for (i=0; archi_table[i].long_archi; i++) {
1948 /* make the call to remove the driver */
1949 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1950 cli->srv_name_slash,
1951 archi_table[i].long_archi,
1954 if (!NT_STATUS_IS_OK(status)) {
1957 if ( !W_ERROR_IS_OK(result) ) {
1958 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1959 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1960 argv[1], archi_table[i].long_archi,
1964 printf ("Driver %s removed for arch [%s].\n", argv[1],
1965 archi_table[i].long_archi);
1972 /****************************************************************************
1973 ****************************************************************************/
1975 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1976 TALLOC_CTX *mem_ctx,
1977 int argc, const char **argv)
1981 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1984 union spoolss_PrintProcessorDirectoryInfo info;
1987 /* parse the command arguments */
1989 printf ("Usage: %s [environment]\n", argv[0]);
1994 environment = argv[1];
1997 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1998 cli->srv_name_slash,
2006 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
2008 buffer = data_blob_talloc_zero(mem_ctx, needed);
2010 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
2011 cli->srv_name_slash,
2021 if (W_ERROR_IS_OK(result)) {
2022 printf("%s\n", info.info1.directory_name);
2028 /****************************************************************************
2029 ****************************************************************************/
2031 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2032 int argc, const char **argv)
2034 struct policy_handle handle;
2037 const char *printername;
2038 union spoolss_AddFormInfo info;
2039 struct spoolss_AddFormInfo1 info1;
2040 struct spoolss_AddFormInfo2 info2;
2043 /* Parse the command arguments */
2045 if (argc < 3 || argc > 5) {
2046 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2050 /* Get a printer handle */
2052 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2054 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2058 if (!W_ERROR_IS_OK(werror))
2061 /* Dummy up some values for the form data */
2064 level = atoi(argv[3]);
2069 info1.flags = SPOOLSS_FORM_USER;
2070 info1.form_name = argv[2];
2071 info1.size.width = 100;
2072 info1.size.height = 100;
2073 info1.area.left = 0;
2074 info1.area.top = 10;
2075 info1.area.right = 20;
2076 info1.area.bottom = 30;
2078 info.info1 = &info1;
2082 info2.flags = SPOOLSS_FORM_USER;
2083 info2.form_name = argv[2];
2084 info2.size.width = 100;
2085 info2.size.height = 100;
2086 info2.area.left = 0;
2087 info2.area.top = 10;
2088 info2.area.right = 20;
2089 info2.area.bottom = 30;
2090 info2.keyword = argv[2];
2091 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2092 info2.mui_dll = NULL;
2093 info2.ressource_id = 0;
2094 info2.display_name = argv[2];
2097 info.info2 = &info2;
2105 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2112 if (is_valid_policy_hnd(&handle))
2113 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2118 /****************************************************************************
2119 ****************************************************************************/
2121 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2122 int argc, const char **argv)
2124 struct policy_handle handle;
2127 const char *printername;
2128 union spoolss_AddFormInfo info;
2129 struct spoolss_AddFormInfo1 info1;
2131 /* Parse the command arguments */
2134 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2138 /* Get a printer handle */
2140 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2142 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2144 SEC_FLAG_MAXIMUM_ALLOWED,
2146 if (!W_ERROR_IS_OK(werror))
2149 /* Dummy up some values for the form data */
2151 info1.flags = SPOOLSS_FORM_PRINTER;
2152 info1.size.width = 100;
2153 info1.size.height = 100;
2154 info1.area.left = 0;
2155 info1.area.top = 1000;
2156 info1.area.right = 2000;
2157 info1.area.bottom = 3000;
2158 info1.form_name = argv[2];
2160 info.info1 = &info1;
2164 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2172 if (is_valid_policy_hnd(&handle))
2173 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2178 /****************************************************************************
2179 ****************************************************************************/
2181 static const char *get_form_flag(int form_flag)
2183 switch (form_flag) {
2184 case SPOOLSS_FORM_USER:
2186 case SPOOLSS_FORM_BUILTIN:
2187 return "FORM_BUILTIN";
2188 case SPOOLSS_FORM_PRINTER:
2189 return "FORM_PRINTER";
2195 /****************************************************************************
2196 ****************************************************************************/
2198 static void display_form_info1(struct spoolss_FormInfo1 *r)
2201 "\tflag: %s (%d)\n" \
2202 "\twidth: %d, length: %d\n" \
2203 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2204 r->form_name, get_form_flag(r->flags), r->flags,
2205 r->size.width, r->size.height,
2206 r->area.left, r->area.right,
2207 r->area.top, r->area.bottom);
2210 /****************************************************************************
2211 ****************************************************************************/
2213 static void display_form_info2(struct spoolss_FormInfo2 *r)
2216 "\tflag: %s (%d)\n" \
2217 "\twidth: %d, length: %d\n" \
2218 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2219 r->form_name, get_form_flag(r->flags), r->flags,
2220 r->size.width, r->size.height,
2221 r->area.left, r->area.right,
2222 r->area.top, r->area.bottom);
2223 printf("\tkeyword: %s\n", r->keyword);
2224 printf("\tstring_type: 0x%08x\n", r->string_type);
2225 printf("\tmui_dll: %s\n", r->mui_dll);
2226 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2227 printf("\tdisplay_name: %s\n", r->display_name);
2228 printf("\tlang_id: %d\n", r->lang_id);
2232 /****************************************************************************
2233 ****************************************************************************/
2235 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2236 int argc, const char **argv)
2238 struct policy_handle handle;
2241 const char *printername;
2243 uint32_t offered = 0;
2244 union spoolss_FormInfo info;
2248 /* Parse the command arguments */
2250 if (argc < 3 || argc > 5) {
2251 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2255 /* Get a printer handle */
2257 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2259 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2261 SEC_FLAG_MAXIMUM_ALLOWED,
2263 if (!W_ERROR_IS_OK(werror))
2267 level = atoi(argv[3]);
2272 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2281 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2282 buffer = data_blob_talloc_zero(mem_ctx, needed);
2284 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2295 if (!NT_STATUS_IS_OK(status)) {
2301 display_form_info1(&info.info1);
2304 display_form_info2(&info.info2);
2309 if (is_valid_policy_hnd(&handle))
2310 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2315 /****************************************************************************
2316 ****************************************************************************/
2318 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2319 TALLOC_CTX *mem_ctx, int argc,
2322 struct policy_handle handle;
2325 const char *printername;
2327 /* Parse the command arguments */
2330 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2334 /* Get a printer handle */
2336 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2338 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2340 SEC_FLAG_MAXIMUM_ALLOWED,
2342 if (!W_ERROR_IS_OK(werror))
2345 /* Delete the form */
2347 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2351 if (!NT_STATUS_IS_OK(status)) {
2352 return ntstatus_to_werror(status);
2356 if (is_valid_policy_hnd(&handle))
2357 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2362 /****************************************************************************
2363 ****************************************************************************/
2365 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2366 TALLOC_CTX *mem_ctx, int argc,
2369 struct policy_handle handle;
2371 const char *printername;
2372 uint32_t num_forms, level = 1, i;
2373 union spoolss_FormInfo *forms;
2375 /* Parse the command arguments */
2377 if (argc < 2 || argc > 4) {
2378 printf ("Usage: %s <printer> [level]\n", argv[0]);
2382 /* Get a printer handle */
2384 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2386 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2388 SEC_FLAG_MAXIMUM_ALLOWED,
2390 if (!W_ERROR_IS_OK(werror))
2394 level = atoi(argv[2]);
2397 /* Enumerate forms */
2399 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2406 if (!W_ERROR_IS_OK(werror))
2409 /* Display output */
2411 for (i = 0; i < num_forms; i++) {
2414 display_form_info1(&forms[i].info1);
2417 display_form_info2(&forms[i].info2);
2423 if (is_valid_policy_hnd(&handle))
2424 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2429 /****************************************************************************
2430 ****************************************************************************/
2432 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2433 TALLOC_CTX *mem_ctx,
2434 int argc, const char **argv)
2438 const char *printername;
2439 struct policy_handle pol;
2440 union spoolss_PrinterInfo info;
2441 enum winreg_Type type;
2442 union spoolss_PrinterData data;
2445 /* parse the command arguments */
2447 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2448 " <value> <data>\n",
2453 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2457 if (strequal(argv[2], "string")) {
2461 if (strequal(argv[2], "binary")) {
2465 if (strequal(argv[2], "dword")) {
2469 if (strequal(argv[2], "multistring")) {
2470 type = REG_MULTI_SZ;
2473 if (type == REG_NONE) {
2474 printf("Unknown data type: %s\n", argv[2]);
2475 result = WERR_INVALID_PARAM;
2479 /* get a printer handle */
2481 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2483 SEC_FLAG_MAXIMUM_ALLOWED,
2485 if (!W_ERROR_IS_OK(result)) {
2489 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2494 if (!W_ERROR_IS_OK(result)) {
2498 printf("%s\n", current_timestring(mem_ctx, true));
2499 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2501 /* Set the printer data */
2505 data.string = talloc_strdup(mem_ctx, argv[4]);
2506 W_ERROR_HAVE_NO_MEMORY(data.string);
2509 data.value = strtoul(argv[4], NULL, 10);
2512 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2514 case REG_MULTI_SZ: {
2516 const char **strings = NULL;
2518 for (i=4; i<argc; i++) {
2519 if (strcmp(argv[i], "NULL") == 0) {
2522 if (!add_string_to_array(mem_ctx, argv[i],
2525 result = WERR_NOMEM;
2529 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2530 if (!data.string_array) {
2531 result = WERR_NOMEM;
2534 for (i=0; i < num_strings; i++) {
2535 data.string_array[i] = strings[i];
2540 printf("Unknown data type: %s\n", argv[2]);
2541 result = WERR_INVALID_PARAM;
2545 result = push_spoolss_PrinterData(mem_ctx, &blob, type, &data);
2546 if (!W_ERROR_IS_OK(result)) {
2550 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2552 argv[3], /* value_name */
2557 if (!W_ERROR_IS_OK(result)) {
2558 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2561 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2563 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2568 if (!W_ERROR_IS_OK(result)) {
2572 printf("%s\n", current_timestring(mem_ctx, true));
2573 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2577 if (is_valid_policy_hnd(&pol)) {
2578 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2584 /****************************************************************************
2585 ****************************************************************************/
2587 static void display_job_info1(struct spoolss_JobInfo1 *r)
2589 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2590 r->user_name, r->document_name, r->text_status, r->pages_printed,
2594 /****************************************************************************
2595 ****************************************************************************/
2597 static void display_job_info2(struct spoolss_JobInfo2 *r)
2599 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2600 r->position, r->job_id,
2601 r->user_name, r->document_name, r->text_status, r->pages_printed,
2602 r->total_pages, r->size);
2605 /****************************************************************************
2606 ****************************************************************************/
2608 static void display_job_info3(struct spoolss_JobInfo3 *r)
2610 printf("jobid[%d], next_jobid[%d]\n",
2611 r->job_id, r->next_job_id);
2614 /****************************************************************************
2615 ****************************************************************************/
2617 static void display_job_info4(struct spoolss_JobInfo4 *r)
2619 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2620 r->position, r->job_id,
2621 r->user_name, r->document_name, r->text_status, r->pages_printed,
2622 r->total_pages, r->size, r->size_high);
2625 /****************************************************************************
2626 ****************************************************************************/
2628 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2629 TALLOC_CTX *mem_ctx, int argc,
2633 uint32_t level = 1, count, i;
2634 const char *printername;
2635 struct policy_handle hnd;
2636 union spoolss_JobInfo *info;
2638 if (argc < 2 || argc > 3) {
2639 printf("Usage: %s printername [level]\n", argv[0]);
2644 level = atoi(argv[2]);
2647 /* Open printer handle */
2649 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2651 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2653 SEC_FLAG_MAXIMUM_ALLOWED,
2655 if (!W_ERROR_IS_OK(result))
2658 /* Enumerate ports */
2660 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2668 if (!W_ERROR_IS_OK(result)) {
2672 for (i = 0; i < count; i++) {
2675 display_job_info1(&info[i].info1);
2678 display_job_info2(&info[i].info2);
2681 d_printf("unknown info level %d\n", level);
2687 if (is_valid_policy_hnd(&hnd)) {
2688 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2694 /****************************************************************************
2695 ****************************************************************************/
2697 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2698 TALLOC_CTX *mem_ctx, int argc,
2702 const char *printername;
2703 struct policy_handle hnd;
2706 union spoolss_JobInfo info;
2708 if (argc < 3 || argc > 4) {
2709 printf("Usage: %s printername job_id [level]\n", argv[0]);
2713 job_id = atoi(argv[2]);
2716 level = atoi(argv[3]);
2719 /* Open printer handle */
2721 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2723 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2725 SEC_FLAG_MAXIMUM_ALLOWED,
2727 if (!W_ERROR_IS_OK(result)) {
2731 /* Enumerate ports */
2733 result = rpccli_spoolss_getjob(cli, mem_ctx,
2740 if (!W_ERROR_IS_OK(result)) {
2746 display_job_info1(&info.info1);
2749 display_job_info2(&info.info2);
2752 display_job_info3(&info.info3);
2755 display_job_info4(&info.info4);
2758 d_printf("unknown info level %d\n", level);
2763 if (is_valid_policy_hnd(&hnd)) {
2764 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2770 /****************************************************************************
2771 ****************************************************************************/
2775 enum spoolss_JobControl val;
2777 {"PAUSE", SPOOLSS_JOB_CONTROL_PAUSE},
2778 {"RESUME", SPOOLSS_JOB_CONTROL_RESUME},
2779 {"CANCEL", SPOOLSS_JOB_CONTROL_CANCEL},
2780 {"RESTART", SPOOLSS_JOB_CONTROL_RESTART},
2781 {"DELETE", SPOOLSS_JOB_CONTROL_DELETE},
2782 {"SEND_TO_PRINTER", SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER},
2783 {"EJECTED", SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED},
2784 {"RETAIN", SPOOLSS_JOB_CONTROL_RETAIN},
2785 {"RELEASE", SPOOLSS_JOB_CONTROL_RELEASE}
2788 static enum spoolss_JobControl parse_setjob_command(const char *cmd)
2792 for (i = 0; i < sizeof(cmdvals)/sizeof(cmdvals[0]); i++) {
2793 if (strequal(cmdvals[i].name, cmd)) {
2794 return cmdvals[i].val;
2797 return (enum spoolss_JobControl)atoi(cmd);
2800 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2801 TALLOC_CTX *mem_ctx, int argc,
2806 const char *printername;
2807 struct policy_handle hnd;
2809 enum spoolss_JobControl command;
2812 printf("Usage: %s printername job_id command\n", argv[0]);
2813 printf("command = [PAUSE|RESUME|CANCEL|RESTART|DELETE|"
2814 "SEND_TO_PRINTER|EJECTED|RETAIN|RELEASE]\n");
2818 job_id = atoi(argv[2]);
2819 command = parse_setjob_command(argv[3]);
2821 /* Open printer handle */
2823 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2825 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2827 SEC_FLAG_MAXIMUM_ALLOWED,
2829 if (!W_ERROR_IS_OK(result)) {
2835 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2842 if (!W_ERROR_IS_OK(result)) {
2847 if (is_valid_policy_hnd(&hnd)) {
2848 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2854 /****************************************************************************
2855 ****************************************************************************/
2857 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2858 TALLOC_CTX *mem_ctx, int argc,
2864 const char *printername;
2865 struct policy_handle hnd;
2866 uint32_t value_offered = 0;
2867 const char *value_name = NULL;
2868 uint32_t value_needed;
2869 enum winreg_Type type;
2870 uint8_t *data = NULL;
2871 uint32_t data_offered = 0;
2872 uint32_t data_needed;
2875 printf("Usage: %s printername\n", argv[0]);
2879 /* Open printer handle */
2881 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2883 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2885 SEC_FLAG_MAXIMUM_ALLOWED,
2887 if (!W_ERROR_IS_OK(result)) {
2891 /* Enumerate data */
2893 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2905 if (!NT_STATUS_IS_OK(status)) {
2906 result = ntstatus_to_werror(status);
2910 if (!W_ERROR_IS_OK(result)) {
2914 data_offered = data_needed;
2915 value_offered = value_needed;
2916 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2917 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2919 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2921 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2932 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2933 struct regval_blob *v;
2935 v = regval_compose(talloc_tos(),
2941 result = WERR_NOMEM;
2945 display_reg_value(v);
2950 if (W_ERROR_V(result) == ERRnomoreitems) {
2951 result = W_ERROR(ERRsuccess);
2955 if (is_valid_policy_hnd(&hnd)) {
2956 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2962 /****************************************************************************
2963 ****************************************************************************/
2965 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2966 TALLOC_CTX *mem_ctx, int argc,
2971 const char *printername;
2972 struct policy_handle hnd;
2974 struct spoolss_PrinterEnumValues *info;
2977 printf("Usage: %s printername <keyname>\n", argv[0]);
2981 /* Open printer handle */
2983 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2985 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2987 SEC_FLAG_MAXIMUM_ALLOWED,
2989 if (!W_ERROR_IS_OK(result)) {
2993 /* Enumerate subkeys */
2995 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
3001 if (!W_ERROR_IS_OK(result)) {
3005 for (i=0; i < count; i++) {
3006 display_printer_data(info[i].value_name,
3009 info[i].data->length);
3013 if (is_valid_policy_hnd(&hnd)) {
3014 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3020 /****************************************************************************
3021 ****************************************************************************/
3023 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
3024 TALLOC_CTX *mem_ctx, int argc,
3028 const char *printername;
3029 const char *keyname = NULL;
3030 struct policy_handle hnd;
3031 const char **key_buffer = NULL;
3033 uint32_t offered = 0;
3035 if (argc < 2 || argc > 4) {
3036 printf("Usage: %s printername [keyname] [offered]\n", argv[0]);
3047 offered = atoi(argv[3]);
3050 /* Open printer handle */
3052 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3054 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3056 SEC_FLAG_MAXIMUM_ALLOWED,
3058 if (!W_ERROR_IS_OK(result)) {
3062 /* Enumerate subkeys */
3064 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
3070 if (!W_ERROR_IS_OK(result)) {
3074 for (i=0; key_buffer && key_buffer[i]; i++) {
3075 printf("%s\n", key_buffer[i]);
3080 if (is_valid_policy_hnd(&hnd)) {
3081 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3087 /****************************************************************************
3088 ****************************************************************************/
3090 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
3091 TALLOC_CTX *mem_ctx, int argc,
3094 const char *printername;
3095 const char *clientname;
3096 struct policy_handle hnd;
3099 struct spoolss_NotifyOption option;
3102 printf("Usage: %s printername\n", argv[0]);
3109 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3111 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3113 SEC_FLAG_MAXIMUM_ALLOWED,
3115 if (!W_ERROR_IS_OK(result)) {
3116 printf("Error opening %s\n", argv[1]);
3120 /* Create spool options */
3125 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3126 if (option.types == NULL) {
3127 result = WERR_NOMEM;
3131 option.types[0].type = PRINTER_NOTIFY_TYPE;
3132 option.types[0].count = 1;
3133 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3134 if (option.types[0].fields == NULL) {
3135 result = WERR_NOMEM;
3138 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3140 option.types[1].type = JOB_NOTIFY_TYPE;
3141 option.types[1].count = 1;
3142 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3143 if (option.types[1].fields == NULL) {
3144 result = WERR_NOMEM;
3147 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3149 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3151 result = WERR_NOMEM;
3157 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3165 if (!W_ERROR_IS_OK(result)) {
3166 printf("Error rffpcnex %s\n", argv[1]);
3171 if (is_valid_policy_hnd(&hnd))
3172 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3177 /****************************************************************************
3178 ****************************************************************************/
3180 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3181 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3183 union spoolss_PrinterInfo info1, info2;
3185 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3187 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3188 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3193 if ( !W_ERROR_IS_OK(werror) ) {
3194 printf("failed (%s)\n", win_errstr(werror));
3195 talloc_destroy(mem_ctx);
3200 printf("Retrieving printer properties for %s...", cli2->desthost);
3201 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3206 if ( !W_ERROR_IS_OK(werror) ) {
3207 printf("failed (%s)\n", win_errstr(werror));
3208 talloc_destroy(mem_ctx);
3213 talloc_destroy(mem_ctx);
3218 /****************************************************************************
3219 ****************************************************************************/
3221 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3222 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3224 union spoolss_PrinterInfo info1, info2;
3226 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3227 struct security_descriptor *sd1, *sd2;
3231 printf("Retrieving printer security for %s...", cli1->desthost);
3232 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3237 if ( !W_ERROR_IS_OK(werror) ) {
3238 printf("failed (%s)\n", win_errstr(werror));
3244 printf("Retrieving printer security for %s...", cli2->desthost);
3245 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3250 if ( !W_ERROR_IS_OK(werror) ) {
3251 printf("failed (%s)\n", win_errstr(werror));
3260 sd1 = info1.info3.secdesc;
3261 sd2 = info2.info3.secdesc;
3263 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3264 printf("NULL secdesc!\n");
3269 if (!security_descriptor_equal( sd1, sd2 ) ) {
3270 printf("Security Descriptors *not* equal!\n");
3275 printf("Security descriptors match\n");
3278 talloc_destroy(mem_ctx);
3283 /****************************************************************************
3284 ****************************************************************************/
3286 extern struct user_auth_info *rpcclient_auth_info;
3288 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3289 TALLOC_CTX *mem_ctx, int argc,
3292 const char *printername;
3293 char *printername_path = NULL;
3294 struct cli_state *cli_server2 = NULL;
3295 struct rpc_pipe_client *cli2 = NULL;
3296 struct policy_handle hPrinter1, hPrinter2;
3301 printf("Usage: %s <printer> <server>\n", argv[0]);
3305 printername = argv[1];
3307 /* first get the connection to the remote server */
3309 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3312 get_cmdline_auth_info_username(rpcclient_auth_info),
3314 get_cmdline_auth_info_password(rpcclient_auth_info),
3315 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3316 get_cmdline_auth_info_signing_state(rpcclient_auth_info));
3318 if ( !NT_STATUS_IS_OK(nt_status) )
3319 return WERR_GENERAL_FAILURE;
3321 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3323 if (!NT_STATUS_IS_OK(nt_status)) {
3324 printf("failed to open spoolss pipe on server %s (%s)\n",
3325 argv[2], nt_errstr(nt_status));
3326 return WERR_GENERAL_FAILURE;
3329 /* now open up both printers */
3331 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3333 printf("Opening %s...", printername_path);
3335 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3339 if ( !W_ERROR_IS_OK(werror) ) {
3340 printf("failed (%s)\n", win_errstr(werror));
3345 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3347 printf("Opening %s...", printername_path);
3348 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3352 if ( !W_ERROR_IS_OK(werror) ) {
3353 printf("failed (%s)\n", win_errstr(werror));
3358 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3359 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3361 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3368 printf("Closing printers...");
3369 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3370 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3373 /* close the second remote connection */
3375 cli_shutdown( cli_server2 );
3379 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3381 printf("print_processor_name: %s\n", r->print_processor_name);
3384 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3385 TALLOC_CTX *mem_ctx, int argc,
3389 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3390 uint32_t num_procs, level = 1, i;
3391 union spoolss_PrintProcessorInfo *procs;
3393 /* Parse the command arguments */
3395 if (argc < 1 || argc > 4) {
3396 printf ("Usage: %s [environment] [level]\n", argv[0]);
3401 environment = argv[1];
3405 level = atoi(argv[2]);
3408 /* Enumerate Print Processors */
3410 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3411 cli->srv_name_slash,
3417 if (!W_ERROR_IS_OK(werror))
3420 /* Display output */
3422 for (i = 0; i < num_procs; i++) {
3425 display_proc_info1(&procs[i].info1);
3434 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3436 printf("name_array: %s\n", r->name_array);
3439 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3440 TALLOC_CTX *mem_ctx, int argc,
3444 const char *print_processor_name = "winprint";
3445 uint32_t num_procs, level = 1, i;
3446 union spoolss_PrintProcDataTypesInfo *procs;
3448 /* Parse the command arguments */
3450 if (argc < 1 || argc > 4) {
3451 printf ("Usage: %s [environment] [level]\n", argv[0]);
3456 print_processor_name = argv[1];
3460 level = atoi(argv[2]);
3463 /* Enumerate Print Processor Data Types */
3465 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3466 cli->srv_name_slash,
3467 print_processor_name,
3472 if (!W_ERROR_IS_OK(werror))
3475 /* Display output */
3477 for (i = 0; i < num_procs; i++) {
3480 display_proc_data_types_info1(&procs[i].info1);
3489 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3491 printf("monitor_name: %s\n", r->monitor_name);
3494 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3496 printf("monitor_name: %s\n", r->monitor_name);
3497 printf("environment: %s\n", r->environment);
3498 printf("dll_name: %s\n", r->dll_name);
3501 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3502 TALLOC_CTX *mem_ctx, int argc,
3506 uint32_t count, level = 1, i;
3507 union spoolss_MonitorInfo *info;
3509 /* Parse the command arguments */
3512 printf("Usage: %s [level]\n", argv[0]);
3517 level = atoi(argv[1]);
3520 /* Enumerate Print Monitors */
3522 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3523 cli->srv_name_slash,
3528 if (!W_ERROR_IS_OK(werror)) {
3532 /* Display output */
3534 for (i = 0; i < count; i++) {
3537 display_monitor1(&info[i].info1);
3540 display_monitor2(&info[i].info2);
3549 static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
3550 TALLOC_CTX *mem_ctx, int argc,
3555 struct policy_handle handle, gdi_handle;
3556 const char *printername;
3557 struct spoolss_DevmodeContainer devmode_ctr;
3559 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3561 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3563 SEC_FLAG_MAXIMUM_ALLOWED,
3565 if (!W_ERROR_IS_OK(result)) {
3569 ZERO_STRUCT(devmode_ctr);
3571 status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx,
3576 if (!W_ERROR_IS_OK(result)) {
3581 if (is_valid_policy_hnd(&gdi_handle)) {
3582 rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL);
3584 if (is_valid_policy_hnd(&handle)) {
3585 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
3591 /* List of commands exported by this module */
3592 struct cmd_set spoolss_commands[] = {
3596 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3597 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3598 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3599 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3600 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3601 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3602 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3603 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3604 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3605 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3606 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3607 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3608 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3609 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3610 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3611 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3612 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3613 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3614 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3615 { "openprinter_ex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3616 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3617 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3618 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3619 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3620 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3621 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3622 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3623 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3624 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3625 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3626 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3627 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3628 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3629 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3630 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
3631 { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" },