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)
696 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
697 *((uint32_t *) value.data_p));
700 rpcstr_pull_talloc(talloc_tos(),
705 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
708 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
710 printf("%s: REG_BINARY:", value.valuename);
712 for (i=0; i<len; i++) {
713 if (hex[i] == '\0') {
728 DATA_BLOB blob = data_blob_const(value.data_p, value.size);
730 if (!pull_reg_multi_sz(NULL, &blob, &values)) {
731 d_printf("pull_reg_multi_sz failed\n");
735 printf("%s: REG_MULTI_SZ: \n", value.valuename);
736 for (i=0; values[i] != NULL; i++) {
737 d_printf("%s\n", values[i]);
743 printf("%s: unknown type %d\n", value.valuename, value.type);
748 /****************************************************************************
749 ****************************************************************************/
751 static void display_printer_data(const char *v,
752 enum winreg_Type type,
753 union spoolss_PrinterData *r)
759 printf("%s: REG_DWORD: 0x%08x\n", v, r->value);
762 printf("%s: REG_SZ: %s\n", v, r->string);
765 char *hex = hex_encode_talloc(NULL,
766 r->binary.data, r->binary.length);
768 printf("%s: REG_BINARY:", v);
770 for (i=0; i<len; i++) {
771 if (hex[i] == '\0') {
784 printf("%s: REG_MULTI_SZ: ", v);
785 for (i=0; r->string_array[i] != NULL; i++) {
786 printf("%s ", r->string_array[i]);
791 printf("%s: unknown type 0x%02x:\n", v, type);
796 /****************************************************************************
797 ****************************************************************************/
799 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
801 int argc, const char **argv)
803 struct policy_handle pol;
806 const char *valuename;
807 enum winreg_Type type;
808 union spoolss_PrinterData data;
811 printf("Usage: %s <printername> <valuename>\n", argv[0]);
812 printf("<printername> of . queries print server\n");
817 /* Open a printer handle */
819 if (strncmp(argv[1], ".", sizeof(".")) == 0)
820 fstrcpy(printername, cli->srv_name_slash);
822 slprintf(printername, sizeof(printername)-1, "%s\\%s",
823 cli->srv_name_slash, argv[1]);
825 /* get a printer handle */
827 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
829 SEC_FLAG_MAXIMUM_ALLOWED,
831 if (!W_ERROR_IS_OK(result))
834 /* Get printer info */
836 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
842 if (!W_ERROR_IS_OK(result))
845 /* Display printer data */
847 display_printer_data(valuename, type, &data);
850 if (is_valid_policy_hnd(&pol))
851 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
856 /****************************************************************************
857 ****************************************************************************/
859 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
861 int argc, const char **argv)
863 struct policy_handle pol;
867 const char *valuename, *keyname;
868 struct regval_blob value;
870 enum winreg_Type type;
871 uint8_t *buffer = NULL;
872 uint32_t offered = 0;
876 printf("Usage: %s <printername> <keyname> <valuename>\n",
878 printf("<printername> of . queries print server\n");
884 /* Open a printer handle */
886 if (strncmp(argv[1], ".", sizeof(".")) == 0)
887 fstrcpy(printername, cli->srv_name_slash);
889 slprintf(printername, sizeof(printername)-1, "%s\\%s",
890 cli->srv_name_slash, argv[1]);
892 /* get a printer handle */
894 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
896 SEC_FLAG_MAXIMUM_ALLOWED,
898 if (!W_ERROR_IS_OK(result))
901 /* Get printer info */
903 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
912 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
914 buffer = talloc_array(mem_ctx, uint8_t, needed);
915 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
926 if (!NT_STATUS_IS_OK(status)) {
930 if (!W_ERROR_IS_OK(result)) {
935 if (!W_ERROR_IS_OK(result))
938 /* Display printer data */
940 fstrcpy(value.valuename, valuename);
943 value.data_p = buffer;
945 display_reg_value(value);
948 if (is_valid_policy_hnd(&pol))
949 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
954 /****************************************************************************
955 ****************************************************************************/
957 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
963 printf("Printer Driver Info 1:\n");
964 printf("\tDriver Name: [%s]\n", r->driver_name);
968 /****************************************************************************
969 ****************************************************************************/
971 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
977 printf("Printer Driver Info 2:\n");
978 printf("\tVersion: [%x]\n", r->version);
979 printf("\tDriver Name: [%s]\n", r->driver_name);
980 printf("\tArchitecture: [%s]\n", r->architecture);
981 printf("\tDriver Path: [%s]\n", r->driver_path);
982 printf("\tDatafile: [%s]\n", r->data_file);
983 printf("\tConfigfile: [%s]\n", r->config_file);
987 /****************************************************************************
988 ****************************************************************************/
990 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
998 printf("Printer Driver Info 3:\n");
999 printf("\tVersion: [%x]\n", r->version);
1000 printf("\tDriver Name: [%s]\n", r->driver_name);
1001 printf("\tArchitecture: [%s]\n", r->architecture);
1002 printf("\tDriver Path: [%s]\n", r->driver_path);
1003 printf("\tDatafile: [%s]\n", r->data_file);
1004 printf("\tConfigfile: [%s]\n", r->config_file);
1005 printf("\tHelpfile: [%s]\n", r->help_file);
1007 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1008 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1011 printf("\tMonitorname: [%s]\n", r->monitor_name);
1012 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1016 /****************************************************************************
1017 ****************************************************************************/
1019 static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1027 printf("Printer Driver Info 4:\n");
1028 printf("\tVersion: [%x]\n", r->version);
1029 printf("\tDriver Name: [%s]\n", r->driver_name);
1030 printf("\tArchitecture: [%s]\n", r->architecture);
1031 printf("\tDriver Path: [%s]\n", r->driver_path);
1032 printf("\tDatafile: [%s]\n", r->data_file);
1033 printf("\tConfigfile: [%s]\n", r->config_file);
1034 printf("\tHelpfile: [%s]\n", r->help_file);
1036 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1037 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1040 printf("\tMonitorname: [%s]\n", r->monitor_name);
1041 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1043 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1044 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1049 /****************************************************************************
1050 ****************************************************************************/
1052 static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1058 printf("Printer Driver Info 5:\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("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1066 printf("\tConfig Version: [0x%x]\n", r->config_version);
1067 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1071 /****************************************************************************
1072 ****************************************************************************/
1074 static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1082 printf("Printer Driver Info 6:\n");
1083 printf("\tVersion: [%x]\n", r->version);
1084 printf("\tDriver Name: [%s]\n", r->driver_name);
1085 printf("\tArchitecture: [%s]\n", r->architecture);
1086 printf("\tDriver Path: [%s]\n", r->driver_path);
1087 printf("\tDatafile: [%s]\n", r->data_file);
1088 printf("\tConfigfile: [%s]\n", r->config_file);
1089 printf("\tHelpfile: [%s]\n", r->help_file);
1091 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1092 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1095 printf("\tMonitorname: [%s]\n", r->monitor_name);
1096 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1098 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1099 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1102 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1103 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1104 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1105 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1106 printf("\tHardware ID: [%s]\n", r->hardware_id);
1107 printf("\tProvider: [%s]\n", r->provider);
1112 /****************************************************************************
1113 ****************************************************************************/
1115 static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1123 printf("Printer Driver Info 8:\n");
1124 printf("\tVersion: [%x]\n", r->version);
1125 printf("\tDriver Name: [%s]\n", r->driver_name);
1126 printf("\tArchitecture: [%s]\n", r->architecture);
1127 printf("\tDriver Path: [%s]\n", r->driver_path);
1128 printf("\tDatafile: [%s]\n", r->data_file);
1129 printf("\tConfigfile: [%s]\n", r->config_file);
1130 printf("\tHelpfile: [%s]\n", r->help_file);
1131 printf("\tMonitorname: [%s]\n", r->monitor_name);
1132 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1134 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1135 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1138 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1139 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1142 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1143 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1144 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1145 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1146 printf("\tHardware ID: [%s]\n", r->hardware_id);
1147 printf("\tProvider: [%s]\n", r->provider);
1148 printf("\tPrint Processor: [%s]\n", r->print_processor);
1149 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1150 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1151 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1153 printf("\tInf Path: [%s]\n", r->inf_path);
1154 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1155 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1156 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1158 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1159 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1160 (long long unsigned int)r->min_inbox_driver_ver_version);
1165 /****************************************************************************
1166 ****************************************************************************/
1168 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1169 TALLOC_CTX *mem_ctx,
1170 int argc, const char **argv)
1172 struct policy_handle pol;
1175 const char *printername;
1177 bool success = false;
1178 union spoolss_DriverInfo info;
1179 uint32_t server_major_version;
1180 uint32_t server_minor_version;
1182 if ((argc == 1) || (argc > 3)) {
1183 printf("Usage: %s <printername> [level]\n", argv[0]);
1187 /* get the arguments need to open the printer handle */
1189 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1192 level = atoi(argv[2]);
1195 /* Open a printer handle */
1197 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1201 if (!W_ERROR_IS_OK(werror)) {
1202 printf("Error opening printer handle for %s!\n", printername);
1206 /* loop through and print driver info level for each architecture */
1208 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1210 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1212 archi_table[i].long_archi,
1215 archi_table[i].version,
1218 &server_major_version,
1219 &server_minor_version);
1220 if (!W_ERROR_IS_OK(werror)) {
1224 /* need at least one success */
1228 printf("\n[%s]\n", archi_table[i].long_archi);
1232 display_print_driver1(&info.info1);
1235 display_print_driver2(&info.info2);
1238 display_print_driver3(&info.info3);
1241 display_print_driver4(&info.info4);
1244 display_print_driver5(&info.info5);
1247 display_print_driver6(&info.info6);
1250 display_print_driver8(&info.info8);
1253 printf("unknown info level %d\n", level);
1260 if (is_valid_policy_hnd(&pol)) {
1261 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1271 /****************************************************************************
1272 ****************************************************************************/
1274 static WERROR enum_driver_by_architecture(struct rpc_pipe_client *cli,
1275 TALLOC_CTX *mem_ctx,
1276 const char *architecture,
1281 union spoolss_DriverInfo *info = NULL;
1284 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1285 cli->srv_name_slash,
1292 if (W_ERROR_EQUAL(werror, WERR_INVALID_ENVIRONMENT)) {
1293 printf("Server does not support environment [%s]\n",
1302 if (!W_ERROR_IS_OK(werror)) {
1303 printf("Error getting driver for environment [%s] - %s\n",
1304 architecture, win_errstr(werror));
1308 printf("\n[%s]\n", architecture);
1312 for (j=0; j < count; j++) {
1313 display_print_driver1(&info[j].info1);
1317 for (j=0; j < count; j++) {
1318 display_print_driver2(&info[j].info2);
1322 for (j=0; j < count; j++) {
1323 display_print_driver3(&info[j].info3);
1327 for (j=0; j < count; j++) {
1328 display_print_driver4(&info[j].info4);
1332 for (j=0; j < count; j++) {
1333 display_print_driver5(&info[j].info5);
1337 for (j=0; j < count; j++) {
1338 display_print_driver6(&info[j].info6);
1342 for (j=0; j < count; j++) {
1343 display_print_driver8(&info[j].info8);
1347 printf("unknown info level %d\n", level);
1348 return WERR_UNKNOWN_LEVEL;
1354 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1355 TALLOC_CTX *mem_ctx,
1356 int argc, const char **argv)
1358 WERROR werror = WERR_OK;
1361 const char *architecture = NULL;
1364 printf("Usage: enumdrivers [level] [architecture]\n");
1369 level = atoi(argv[1]);
1373 architecture = argv[2];
1377 return enum_driver_by_architecture(cli, mem_ctx,
1382 /* loop through and print driver info level for each architecture */
1383 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1384 /* check to see if we already asked for this architecture string */
1386 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1390 werror = enum_driver_by_architecture(cli, mem_ctx,
1391 archi_table[i].long_archi,
1393 if (!W_ERROR_IS_OK(werror)) {
1401 /****************************************************************************
1402 ****************************************************************************/
1404 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1406 printf("\tDirectory Name:[%s]\n", r->directory_name);
1409 /****************************************************************************
1410 ****************************************************************************/
1412 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1413 TALLOC_CTX *mem_ctx,
1414 int argc, const char **argv)
1418 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1421 union spoolss_DriverDirectoryInfo info;
1425 printf("Usage: %s [environment]\n", argv[0]);
1429 /* Get the arguments need to open the printer handle */
1435 /* Get the directory. Only use Info level 1 */
1437 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1438 cli->srv_name_slash,
1446 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1448 buffer = data_blob_talloc_zero(mem_ctx, needed);
1450 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1451 cli->srv_name_slash,
1461 if (W_ERROR_IS_OK(result)) {
1462 display_printdriverdir_1(&info.info1);
1468 /****************************************************************************
1469 ****************************************************************************/
1471 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1472 struct spoolss_AddDriverInfo3 *info,
1478 for (i=0; archi_table[i].long_archi != NULL; i++)
1480 if (strcmp(arch, archi_table[i].short_archi) == 0)
1482 info->version = archi_table[i].version;
1483 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1488 if (archi_table[i].long_archi == NULL)
1490 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1497 /**************************************************************************
1498 wrapper for strtok to get the next parameter from a delimited list.
1499 Needed to handle the empty parameter string denoted by "NULL"
1500 *************************************************************************/
1502 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1503 const char *delim, const char **dest,
1508 /* get the next token */
1509 ptr = strtok_r(str, delim, saveptr);
1511 /* a string of 'NULL' is used to represent an empty
1512 parameter because two consecutive delimiters
1513 will not return an empty string. See man strtok(3)
1515 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1520 *dest = talloc_strdup(mem_ctx, ptr);
1526 /********************************************************************************
1527 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1528 string in the form of
1529 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1530 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1531 <Default Data Type>:<Comma Separated list of Files>
1532 *******************************************************************************/
1534 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1539 char *saveptr = NULL;
1540 struct spoolss_StringArray *deps;
1541 const char **file_array = NULL;
1544 /* fill in the UNISTR fields */
1545 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1546 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1547 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1548 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1549 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1550 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1551 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1553 /* <Comma Separated List of Dependent Files> */
1554 /* save the beginning of the string */
1555 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1558 /* begin to strip out each filename */
1559 str = strtok_r(str, ",", &saveptr);
1561 /* no dependent files, we are done */
1566 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1571 while (str != NULL) {
1572 add_string_to_array(deps, str, &file_array, &count);
1573 str = strtok_r(NULL, ",", &saveptr);
1576 deps->string = talloc_zero_array(deps, const char *, count + 1);
1577 if (!deps->string) {
1581 for (i=0; i < count; i++) {
1582 deps->string[i] = file_array[i];
1585 r->dependent_files = deps;
1590 /****************************************************************************
1591 ****************************************************************************/
1593 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1594 TALLOC_CTX *mem_ctx,
1595 int argc, const char **argv)
1600 struct spoolss_AddDriverInfoCtr info_ctr;
1601 struct spoolss_AddDriverInfo3 info3;
1605 /* parse the command arguments */
1606 if (argc != 3 && argc != 4)
1608 printf ("Usage: %s <Environment> \\\n", argv[0]);
1609 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1610 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1611 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1612 printf ("\t[version]\n");
1617 /* Fill in the spoolss_AddDriverInfo3 struct */
1620 arch = cmd_spoolss_get_short_archi(argv[1]);
1622 printf ("Error Unknown architechture [%s]\n", argv[1]);
1623 return WERR_INVALID_PARAM;
1626 set_drv_info_3_env(mem_ctx, &info3, arch);
1628 driver_args = talloc_strdup( mem_ctx, argv[2] );
1629 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1631 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1632 return WERR_INVALID_PARAM;
1635 /* if printer driver version specified, override the default version
1636 * used by the architecture. This allows installation of Windows
1637 * 2000 (version 3) printer drivers. */
1640 info3.version = atoi(argv[3]);
1644 info_ctr.level = level;
1645 info_ctr.info.info3 = &info3;
1647 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1648 cli->srv_name_slash,
1651 if (!NT_STATUS_IS_OK(status)) {
1652 return ntstatus_to_werror(status);
1654 if (W_ERROR_IS_OK(result)) {
1655 printf ("Printer Driver %s successfully installed.\n",
1663 /****************************************************************************
1664 ****************************************************************************/
1666 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1667 TALLOC_CTX *mem_ctx,
1668 int argc, const char **argv)
1671 struct spoolss_SetPrinterInfoCtr info_ctr;
1672 struct spoolss_SetPrinterInfo2 info2;
1674 /* parse the command arguments */
1677 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1681 /* Fill in the DRIVER_INFO_2 struct */
1684 info2.printername = argv[1];
1685 info2.drivername = argv[3];
1686 info2.sharename = argv[2];
1687 info2.portname = argv[4];
1688 info2.comment = "Created by rpcclient";
1689 info2.printprocessor = "winprint";
1690 info2.datatype = "RAW";
1691 info2.devmode = NULL;
1692 info2.secdesc = NULL;
1693 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1695 info2.defaultpriority = 0;
1696 info2.starttime = 0;
1697 info2.untiltime = 0;
1699 /* These three fields must not be used by AddPrinter()
1700 as defined in the MS Platform SDK documentation..
1704 info2.averageppm = 0;
1708 info_ctr.info.info2 = &info2;
1710 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1712 if (W_ERROR_IS_OK(result))
1713 printf ("Printer %s successfully installed.\n", argv[1]);
1718 /****************************************************************************
1719 ****************************************************************************/
1721 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1722 TALLOC_CTX *mem_ctx,
1723 int argc, const char **argv)
1725 struct policy_handle pol;
1729 const char *printername;
1730 union spoolss_PrinterInfo info;
1731 struct spoolss_SetPrinterInfoCtr info_ctr;
1732 struct spoolss_DevmodeContainer devmode_ctr;
1733 struct sec_desc_buf secdesc_ctr;
1735 ZERO_STRUCT(devmode_ctr);
1736 ZERO_STRUCT(secdesc_ctr);
1738 /* parse the command arguments */
1741 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1745 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1747 /* Get a printer handle */
1749 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1753 if (!W_ERROR_IS_OK(result))
1756 /* Get printer info */
1758 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1763 if (!W_ERROR_IS_OK(result)) {
1764 printf ("Unable to retrieve printer information!\n");
1768 /* Set the printer driver */
1770 info.info2.drivername = argv[2];
1771 info.info2.devmode = NULL;
1772 info.info2.secdesc = NULL;
1775 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
1777 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1784 if (!W_ERROR_IS_OK(result)) {
1785 printf("SetPrinter call failed!\n");
1789 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1794 if (is_valid_policy_hnd(&pol))
1795 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1801 /****************************************************************************
1802 ****************************************************************************/
1804 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1805 TALLOC_CTX *mem_ctx,
1806 int argc, const char **argv)
1808 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1814 const char *arch = NULL;
1815 uint32_t delete_flags = 0;
1817 /* parse the command arguments */
1818 if (argc < 2 || argc > 4) {
1819 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1826 vers = atoi (argv[3]);
1829 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1832 /* delete the driver for all architectures */
1833 for (i=0; archi_table[i].long_archi; i++) {
1835 if (arch && !strequal( archi_table[i].long_archi, arch))
1838 if (vers >= 0 && archi_table[i].version != vers)
1841 /* make the call to remove the driver */
1842 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1843 cli->srv_name_slash,
1844 archi_table[i].long_archi,
1847 archi_table[i].version,
1850 if ( !W_ERROR_IS_OK(result) )
1852 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1853 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1854 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1859 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1860 archi_table[i].long_archi, archi_table[i].version);
1869 /****************************************************************************
1870 ****************************************************************************/
1872 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1873 TALLOC_CTX *mem_ctx,
1874 int argc, const char **argv)
1876 WERROR result = WERR_OK;
1880 /* parse the command arguments */
1882 printf ("Usage: %s <driver>\n", argv[0]);
1886 /* delete the driver for all architectures */
1887 for (i=0; archi_table[i].long_archi; i++) {
1888 /* make the call to remove the driver */
1889 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1890 cli->srv_name_slash,
1891 archi_table[i].long_archi,
1894 if (!NT_STATUS_IS_OK(status)) {
1897 if ( !W_ERROR_IS_OK(result) ) {
1898 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1899 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1900 argv[1], archi_table[i].long_archi,
1904 printf ("Driver %s removed for arch [%s].\n", argv[1],
1905 archi_table[i].long_archi);
1912 /****************************************************************************
1913 ****************************************************************************/
1915 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1916 TALLOC_CTX *mem_ctx,
1917 int argc, const char **argv)
1921 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1924 union spoolss_PrintProcessorDirectoryInfo info;
1927 /* parse the command arguments */
1929 printf ("Usage: %s [environment]\n", argv[0]);
1934 environment = argv[1];
1937 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1938 cli->srv_name_slash,
1946 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1948 buffer = data_blob_talloc_zero(mem_ctx, needed);
1950 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1951 cli->srv_name_slash,
1961 if (W_ERROR_IS_OK(result)) {
1962 printf("%s\n", info.info1.directory_name);
1968 /****************************************************************************
1969 ****************************************************************************/
1971 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1972 int argc, const char **argv)
1974 struct policy_handle handle;
1977 const char *printername;
1978 union spoolss_AddFormInfo info;
1979 struct spoolss_AddFormInfo1 info1;
1980 struct spoolss_AddFormInfo2 info2;
1983 /* Parse the command arguments */
1985 if (argc < 3 || argc > 5) {
1986 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
1990 /* Get a printer handle */
1992 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1994 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1998 if (!W_ERROR_IS_OK(werror))
2001 /* Dummy up some values for the form data */
2004 level = atoi(argv[3]);
2009 info1.flags = SPOOLSS_FORM_USER;
2010 info1.form_name = argv[2];
2011 info1.size.width = 100;
2012 info1.size.height = 100;
2013 info1.area.left = 0;
2014 info1.area.top = 10;
2015 info1.area.right = 20;
2016 info1.area.bottom = 30;
2018 info.info1 = &info1;
2022 info2.flags = SPOOLSS_FORM_USER;
2023 info2.form_name = argv[2];
2024 info2.size.width = 100;
2025 info2.size.height = 100;
2026 info2.area.left = 0;
2027 info2.area.top = 10;
2028 info2.area.right = 20;
2029 info2.area.bottom = 30;
2030 info2.keyword = argv[2];
2031 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2032 info2.mui_dll = NULL;
2033 info2.ressource_id = 0;
2034 info2.display_name = argv[2];
2037 info.info2 = &info2;
2045 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2052 if (is_valid_policy_hnd(&handle))
2053 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2058 /****************************************************************************
2059 ****************************************************************************/
2061 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2062 int argc, const char **argv)
2064 struct policy_handle handle;
2067 const char *printername;
2068 union spoolss_AddFormInfo info;
2069 struct spoolss_AddFormInfo1 info1;
2071 /* Parse the command arguments */
2074 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2078 /* Get a printer handle */
2080 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2082 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2084 SEC_FLAG_MAXIMUM_ALLOWED,
2086 if (!W_ERROR_IS_OK(werror))
2089 /* Dummy up some values for the form data */
2091 info1.flags = SPOOLSS_FORM_PRINTER;
2092 info1.size.width = 100;
2093 info1.size.height = 100;
2094 info1.area.left = 0;
2095 info1.area.top = 1000;
2096 info1.area.right = 2000;
2097 info1.area.bottom = 3000;
2098 info1.form_name = argv[2];
2100 info.info1 = &info1;
2104 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2112 if (is_valid_policy_hnd(&handle))
2113 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2118 /****************************************************************************
2119 ****************************************************************************/
2121 static const char *get_form_flag(int form_flag)
2123 switch (form_flag) {
2124 case SPOOLSS_FORM_USER:
2126 case SPOOLSS_FORM_BUILTIN:
2127 return "FORM_BUILTIN";
2128 case SPOOLSS_FORM_PRINTER:
2129 return "FORM_PRINTER";
2135 /****************************************************************************
2136 ****************************************************************************/
2138 static void display_form_info1(struct spoolss_FormInfo1 *r)
2141 "\tflag: %s (%d)\n" \
2142 "\twidth: %d, length: %d\n" \
2143 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2144 r->form_name, get_form_flag(r->flags), r->flags,
2145 r->size.width, r->size.height,
2146 r->area.left, r->area.right,
2147 r->area.top, r->area.bottom);
2150 /****************************************************************************
2151 ****************************************************************************/
2153 static void display_form_info2(struct spoolss_FormInfo2 *r)
2156 "\tflag: %s (%d)\n" \
2157 "\twidth: %d, length: %d\n" \
2158 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2159 r->form_name, get_form_flag(r->flags), r->flags,
2160 r->size.width, r->size.height,
2161 r->area.left, r->area.right,
2162 r->area.top, r->area.bottom);
2163 printf("\tkeyword: %s\n", r->keyword);
2164 printf("\tstring_type: 0x%08x\n", r->string_type);
2165 printf("\tmui_dll: %s\n", r->mui_dll);
2166 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2167 printf("\tdisplay_name: %s\n", r->display_name);
2168 printf("\tlang_id: %d\n", r->lang_id);
2172 /****************************************************************************
2173 ****************************************************************************/
2175 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2176 int argc, const char **argv)
2178 struct policy_handle handle;
2181 const char *printername;
2183 uint32_t offered = 0;
2184 union spoolss_FormInfo info;
2188 /* Parse the command arguments */
2190 if (argc < 3 || argc > 5) {
2191 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2195 /* Get a printer handle */
2197 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2199 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2201 SEC_FLAG_MAXIMUM_ALLOWED,
2203 if (!W_ERROR_IS_OK(werror))
2207 level = atoi(argv[3]);
2212 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2221 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2222 buffer = data_blob_talloc_zero(mem_ctx, needed);
2224 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2235 if (!NT_STATUS_IS_OK(status)) {
2241 display_form_info1(&info.info1);
2244 display_form_info2(&info.info2);
2249 if (is_valid_policy_hnd(&handle))
2250 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2255 /****************************************************************************
2256 ****************************************************************************/
2258 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2259 TALLOC_CTX *mem_ctx, int argc,
2262 struct policy_handle handle;
2265 const char *printername;
2267 /* Parse the command arguments */
2270 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2274 /* Get a printer handle */
2276 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2278 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2280 SEC_FLAG_MAXIMUM_ALLOWED,
2282 if (!W_ERROR_IS_OK(werror))
2285 /* Delete the form */
2287 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2291 if (!NT_STATUS_IS_OK(status)) {
2292 return ntstatus_to_werror(status);
2296 if (is_valid_policy_hnd(&handle))
2297 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2302 /****************************************************************************
2303 ****************************************************************************/
2305 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2306 TALLOC_CTX *mem_ctx, int argc,
2309 struct policy_handle handle;
2311 const char *printername;
2312 uint32_t num_forms, level = 1, i;
2313 union spoolss_FormInfo *forms;
2315 /* Parse the command arguments */
2317 if (argc < 2 || argc > 4) {
2318 printf ("Usage: %s <printer> [level]\n", argv[0]);
2322 /* Get a printer handle */
2324 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2326 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2328 SEC_FLAG_MAXIMUM_ALLOWED,
2330 if (!W_ERROR_IS_OK(werror))
2334 level = atoi(argv[2]);
2337 /* Enumerate forms */
2339 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2346 if (!W_ERROR_IS_OK(werror))
2349 /* Display output */
2351 for (i = 0; i < num_forms; i++) {
2354 display_form_info1(&forms[i].info1);
2357 display_form_info2(&forms[i].info2);
2363 if (is_valid_policy_hnd(&handle))
2364 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2369 /****************************************************************************
2370 ****************************************************************************/
2372 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2373 TALLOC_CTX *mem_ctx,
2374 int argc, const char **argv)
2378 const char *printername;
2379 struct policy_handle pol;
2380 union spoolss_PrinterInfo info;
2381 enum winreg_Type type;
2382 union spoolss_PrinterData data;
2384 /* parse the command arguments */
2386 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2387 " <value> <data>\n",
2389 result = WERR_INVALID_PARAM;
2393 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2397 if (strequal(argv[2], "string")) {
2401 if (strequal(argv[2], "binary")) {
2405 if (strequal(argv[2], "dword")) {
2409 if (strequal(argv[2], "multistring")) {
2410 type = REG_MULTI_SZ;
2413 if (type == REG_NONE) {
2414 printf("Unknown data type: %s\n", argv[2]);
2415 result = WERR_INVALID_PARAM;
2419 /* get a printer handle */
2421 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2423 SEC_FLAG_MAXIMUM_ALLOWED,
2425 if (!W_ERROR_IS_OK(result)) {
2429 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2434 if (!W_ERROR_IS_OK(result)) {
2438 printf("%s\n", current_timestring(mem_ctx, true));
2439 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2441 /* Set the printer data */
2445 data.string = talloc_strdup(mem_ctx, argv[4]);
2446 W_ERROR_HAVE_NO_MEMORY(data.string);
2449 data.value = strtoul(argv[4], NULL, 10);
2452 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2454 case REG_MULTI_SZ: {
2456 const char **strings = NULL;
2458 for (i=4; i<argc; i++) {
2459 if (strcmp(argv[i], "NULL") == 0) {
2462 if (!add_string_to_array(mem_ctx, argv[i],
2465 result = WERR_NOMEM;
2469 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2470 if (!data.string_array) {
2471 result = WERR_NOMEM;
2474 for (i=0; i < num_strings; i++) {
2475 data.string_array[i] = strings[i];
2480 printf("Unknown data type: %s\n", argv[2]);
2481 result = WERR_INVALID_PARAM;
2485 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2487 argv[3], /* value_name */
2490 0, /* autocalculated size */
2492 if (!W_ERROR_IS_OK(result)) {
2493 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2496 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2498 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2503 if (!W_ERROR_IS_OK(result)) {
2507 printf("%s\n", current_timestring(mem_ctx, true));
2508 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2512 if (is_valid_policy_hnd(&pol)) {
2513 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2519 /****************************************************************************
2520 ****************************************************************************/
2522 static void display_job_info1(struct spoolss_JobInfo1 *r)
2524 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2525 r->user_name, r->document_name, r->text_status, r->pages_printed,
2529 /****************************************************************************
2530 ****************************************************************************/
2532 static void display_job_info2(struct spoolss_JobInfo2 *r)
2534 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2535 r->position, r->job_id,
2536 r->user_name, r->document_name, r->text_status, r->pages_printed,
2537 r->total_pages, r->size);
2540 /****************************************************************************
2541 ****************************************************************************/
2543 static void display_job_info3(struct spoolss_JobInfo3 *r)
2545 printf("jobid[%d], next_jobid[%d]\n",
2546 r->job_id, r->next_job_id);
2549 /****************************************************************************
2550 ****************************************************************************/
2552 static void display_job_info4(struct spoolss_JobInfo4 *r)
2554 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2555 r->position, r->job_id,
2556 r->user_name, r->document_name, r->text_status, r->pages_printed,
2557 r->total_pages, r->size, r->size_high);
2560 /****************************************************************************
2561 ****************************************************************************/
2563 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2564 TALLOC_CTX *mem_ctx, int argc,
2568 uint32_t level = 1, count, i;
2569 const char *printername;
2570 struct policy_handle hnd;
2571 union spoolss_JobInfo *info;
2573 if (argc < 2 || argc > 3) {
2574 printf("Usage: %s printername [level]\n", argv[0]);
2579 level = atoi(argv[2]);
2582 /* Open printer handle */
2584 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2586 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2588 SEC_FLAG_MAXIMUM_ALLOWED,
2590 if (!W_ERROR_IS_OK(result))
2593 /* Enumerate ports */
2595 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2603 if (!W_ERROR_IS_OK(result)) {
2607 for (i = 0; i < count; i++) {
2610 display_job_info1(&info[i].info1);
2613 display_job_info2(&info[i].info2);
2616 d_printf("unknown info level %d\n", level);
2622 if (is_valid_policy_hnd(&hnd)) {
2623 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2629 /****************************************************************************
2630 ****************************************************************************/
2632 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2633 TALLOC_CTX *mem_ctx, int argc,
2637 const char *printername;
2638 struct policy_handle hnd;
2641 union spoolss_JobInfo info;
2643 if (argc < 3 || argc > 4) {
2644 printf("Usage: %s printername job_id [level]\n", argv[0]);
2648 job_id = atoi(argv[2]);
2651 level = atoi(argv[3]);
2654 /* Open printer handle */
2656 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2658 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2660 SEC_FLAG_MAXIMUM_ALLOWED,
2662 if (!W_ERROR_IS_OK(result)) {
2666 /* Enumerate ports */
2668 result = rpccli_spoolss_getjob(cli, mem_ctx,
2675 if (!W_ERROR_IS_OK(result)) {
2681 display_job_info1(&info.info1);
2684 display_job_info2(&info.info2);
2687 display_job_info3(&info.info3);
2690 display_job_info4(&info.info4);
2693 d_printf("unknown info level %d\n", level);
2698 if (is_valid_policy_hnd(&hnd)) {
2699 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2705 /****************************************************************************
2706 ****************************************************************************/
2708 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2709 TALLOC_CTX *mem_ctx, int argc,
2714 const char *printername;
2715 struct policy_handle hnd;
2717 enum spoolss_JobControl command;
2720 printf("Usage: %s printername job_id command\n", argv[0]);
2724 job_id = atoi(argv[2]);
2725 command = atoi(argv[3]);
2727 /* Open printer handle */
2729 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2731 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2733 SEC_FLAG_MAXIMUM_ALLOWED,
2735 if (!W_ERROR_IS_OK(result)) {
2741 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2748 if (!W_ERROR_IS_OK(result)) {
2753 if (is_valid_policy_hnd(&hnd)) {
2754 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2760 /****************************************************************************
2761 ****************************************************************************/
2763 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2764 TALLOC_CTX *mem_ctx, int argc,
2770 const char *printername;
2771 struct policy_handle hnd;
2772 uint32_t value_offered = 0;
2773 const char *value_name = NULL;
2774 uint32_t value_needed;
2775 enum winreg_Type type;
2776 uint8_t *data = NULL;
2777 uint32_t data_offered = 0;
2778 uint32_t data_needed;
2781 printf("Usage: %s printername\n", argv[0]);
2785 /* Open printer handle */
2787 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2789 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2791 SEC_FLAG_MAXIMUM_ALLOWED,
2793 if (!W_ERROR_IS_OK(result)) {
2797 /* Enumerate data */
2799 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2811 data_offered = data_needed;
2812 value_offered = value_needed;
2813 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2814 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2816 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2818 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2829 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2830 struct regval_blob v;
2831 fstrcpy(v.valuename, value_name);
2833 v.size = data_offered;
2835 display_reg_value(v);
2839 if (W_ERROR_V(result) == ERRnomoreitems) {
2840 result = W_ERROR(ERRsuccess);
2844 if (is_valid_policy_hnd(&hnd)) {
2845 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2851 /****************************************************************************
2852 ****************************************************************************/
2854 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2855 TALLOC_CTX *mem_ctx, int argc,
2860 const char *printername;
2861 struct policy_handle hnd;
2863 struct spoolss_PrinterEnumValues *info;
2866 printf("Usage: %s printername <keyname>\n", argv[0]);
2870 /* Open printer handle */
2872 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2874 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2876 SEC_FLAG_MAXIMUM_ALLOWED,
2878 if (!W_ERROR_IS_OK(result)) {
2882 /* Enumerate subkeys */
2884 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
2890 if (!W_ERROR_IS_OK(result)) {
2894 for (i=0; i < count; i++) {
2895 display_printer_data(info[i].value_name,
2901 if (is_valid_policy_hnd(&hnd)) {
2902 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2908 /****************************************************************************
2909 ****************************************************************************/
2911 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
2912 TALLOC_CTX *mem_ctx, int argc,
2916 const char *printername;
2917 const char *keyname = NULL;
2918 struct policy_handle hnd;
2919 const char **key_buffer = NULL;
2922 if (argc < 2 || argc > 3) {
2923 printf("Usage: %s printername [keyname]\n", argv[0]);
2933 /* Open printer handle */
2935 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2937 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2939 SEC_FLAG_MAXIMUM_ALLOWED,
2941 if (!W_ERROR_IS_OK(result)) {
2945 /* Enumerate subkeys */
2947 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
2953 if (!W_ERROR_IS_OK(result)) {
2957 for (i=0; key_buffer && key_buffer[i]; i++) {
2958 printf("%s\n", key_buffer[i]);
2963 if (is_valid_policy_hnd(&hnd)) {
2964 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2970 /****************************************************************************
2971 ****************************************************************************/
2973 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2974 TALLOC_CTX *mem_ctx, int argc,
2977 const char *printername;
2978 const char *clientname;
2979 struct policy_handle hnd;
2982 struct spoolss_NotifyOption option;
2985 printf("Usage: %s printername\n", argv[0]);
2992 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2994 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2996 SEC_FLAG_MAXIMUM_ALLOWED,
2998 if (!W_ERROR_IS_OK(result)) {
2999 printf("Error opening %s\n", argv[1]);
3003 /* Create spool options */
3008 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3009 if (option.types == NULL) {
3010 result = WERR_NOMEM;
3014 option.types[0].type = PRINTER_NOTIFY_TYPE;
3015 option.types[0].count = 1;
3016 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3017 if (option.types[0].fields == NULL) {
3018 result = WERR_NOMEM;
3021 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3023 option.types[1].type = JOB_NOTIFY_TYPE;
3024 option.types[1].count = 1;
3025 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3026 if (option.types[1].fields == NULL) {
3027 result = WERR_NOMEM;
3030 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3032 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3034 result = WERR_NOMEM;
3040 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3048 if (!W_ERROR_IS_OK(result)) {
3049 printf("Error rffpcnex %s\n", argv[1]);
3054 if (is_valid_policy_hnd(&hnd))
3055 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3060 /****************************************************************************
3061 ****************************************************************************/
3063 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3064 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3066 union spoolss_PrinterInfo info1, info2;
3068 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3070 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3071 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3076 if ( !W_ERROR_IS_OK(werror) ) {
3077 printf("failed (%s)\n", win_errstr(werror));
3078 talloc_destroy(mem_ctx);
3083 printf("Retrieving printer properties for %s...", cli2->desthost);
3084 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3089 if ( !W_ERROR_IS_OK(werror) ) {
3090 printf("failed (%s)\n", win_errstr(werror));
3091 talloc_destroy(mem_ctx);
3096 talloc_destroy(mem_ctx);
3101 /****************************************************************************
3102 ****************************************************************************/
3104 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3105 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3107 union spoolss_PrinterInfo info1, info2;
3109 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3110 SEC_DESC *sd1, *sd2;
3114 printf("Retrieving printer security for %s...", cli1->desthost);
3115 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3120 if ( !W_ERROR_IS_OK(werror) ) {
3121 printf("failed (%s)\n", win_errstr(werror));
3127 printf("Retrieving printer security for %s...", cli2->desthost);
3128 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3133 if ( !W_ERROR_IS_OK(werror) ) {
3134 printf("failed (%s)\n", win_errstr(werror));
3143 sd1 = info1.info3.secdesc;
3144 sd2 = info2.info3.secdesc;
3146 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3147 printf("NULL secdesc!\n");
3152 if (!security_descriptor_equal( sd1, sd2 ) ) {
3153 printf("Security Descriptors *not* equal!\n");
3158 printf("Security descriptors match\n");
3161 talloc_destroy(mem_ctx);
3166 /****************************************************************************
3167 ****************************************************************************/
3169 extern struct user_auth_info *rpcclient_auth_info;
3171 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3172 TALLOC_CTX *mem_ctx, int argc,
3175 const char *printername;
3176 char *printername_path = NULL;
3177 struct cli_state *cli_server2 = NULL;
3178 struct rpc_pipe_client *cli2 = NULL;
3179 struct policy_handle hPrinter1, hPrinter2;
3184 printf("Usage: %s <printer> <server>\n", argv[0]);
3188 printername = argv[1];
3190 /* first get the connection to the remote server */
3192 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3195 get_cmdline_auth_info_username(rpcclient_auth_info),
3197 get_cmdline_auth_info_password(rpcclient_auth_info),
3198 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3199 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3201 if ( !NT_STATUS_IS_OK(nt_status) )
3202 return WERR_GENERAL_FAILURE;
3204 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3206 if (!NT_STATUS_IS_OK(nt_status)) {
3207 printf("failed to open spoolss pipe on server %s (%s)\n",
3208 argv[2], nt_errstr(nt_status));
3209 return WERR_GENERAL_FAILURE;
3212 /* now open up both printers */
3214 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3216 printf("Opening %s...", printername_path);
3218 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3222 if ( !W_ERROR_IS_OK(werror) ) {
3223 printf("failed (%s)\n", win_errstr(werror));
3228 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3230 printf("Opening %s...", printername_path);
3231 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3235 if ( !W_ERROR_IS_OK(werror) ) {
3236 printf("failed (%s)\n", win_errstr(werror));
3241 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3242 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3244 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3251 printf("Closing printers...");
3252 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3253 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3256 /* close the second remote connection */
3258 cli_shutdown( cli_server2 );
3262 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3264 printf("print_processor_name: %s\n", r->print_processor_name);
3267 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3268 TALLOC_CTX *mem_ctx, int argc,
3272 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3273 uint32_t num_procs, level = 1, i;
3274 union spoolss_PrintProcessorInfo *procs;
3276 /* Parse the command arguments */
3278 if (argc < 1 || argc > 4) {
3279 printf ("Usage: %s [environment] [level]\n", argv[0]);
3284 environment = argv[1];
3288 level = atoi(argv[2]);
3291 /* Enumerate Print Processors */
3293 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3294 cli->srv_name_slash,
3300 if (!W_ERROR_IS_OK(werror))
3303 /* Display output */
3305 for (i = 0; i < num_procs; i++) {
3308 display_proc_info1(&procs[i].info1);
3317 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3319 printf("name_array: %s\n", r->name_array);
3322 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3323 TALLOC_CTX *mem_ctx, int argc,
3327 const char *print_processor_name = "winprint";
3328 uint32_t num_procs, level = 1, i;
3329 union spoolss_PrintProcDataTypesInfo *procs;
3331 /* Parse the command arguments */
3333 if (argc < 1 || argc > 4) {
3334 printf ("Usage: %s [environment] [level]\n", argv[0]);
3339 print_processor_name = argv[1];
3343 level = atoi(argv[2]);
3346 /* Enumerate Print Processor Data Types */
3348 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3349 cli->srv_name_slash,
3350 print_processor_name,
3355 if (!W_ERROR_IS_OK(werror))
3358 /* Display output */
3360 for (i = 0; i < num_procs; i++) {
3363 display_proc_data_types_info1(&procs[i].info1);
3372 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3374 printf("monitor_name: %s\n", r->monitor_name);
3377 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3379 printf("monitor_name: %s\n", r->monitor_name);
3380 printf("environment: %s\n", r->environment);
3381 printf("dll_name: %s\n", r->dll_name);
3384 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3385 TALLOC_CTX *mem_ctx, int argc,
3389 uint32_t count, level = 1, i;
3390 union spoolss_MonitorInfo *info;
3392 /* Parse the command arguments */
3395 printf("Usage: %s [level]\n", argv[0]);
3400 level = atoi(argv[1]);
3403 /* Enumerate Print Monitors */
3405 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3406 cli->srv_name_slash,
3411 if (!W_ERROR_IS_OK(werror)) {
3415 /* Display output */
3417 for (i = 0; i < count; i++) {
3420 display_monitor1(&info[i].info1);
3423 display_monitor2(&info[i].info2);
3432 static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
3433 TALLOC_CTX *mem_ctx, int argc,
3438 struct policy_handle handle, gdi_handle;
3439 const char *printername;
3440 struct spoolss_DevmodeContainer devmode_ctr;
3442 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3444 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3446 SEC_FLAG_MAXIMUM_ALLOWED,
3448 if (!W_ERROR_IS_OK(result)) {
3452 ZERO_STRUCT(devmode_ctr);
3454 status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx,
3459 if (!W_ERROR_IS_OK(result)) {
3464 if (is_valid_policy_hnd(&gdi_handle)) {
3465 rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL);
3467 if (is_valid_policy_hnd(&handle)) {
3468 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
3474 /* List of commands exported by this module */
3475 struct cmd_set spoolss_commands[] = {
3479 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3480 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3481 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3482 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3483 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3484 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3485 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3486 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3487 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3488 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3489 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3490 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3491 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3492 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3493 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3494 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3495 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3496 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3497 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3498 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3499 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3500 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3501 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3502 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3503 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3504 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3505 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3506 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3507 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3508 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3509 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3510 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3511 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3512 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
3513 { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" },