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(REGISTRY_VALUE 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') {
726 uint32_t i, num_values;
729 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
730 value.size, &num_values,
732 d_printf("reg_pull_multi_sz failed\n");
736 printf("%s: REG_MULTI_SZ: \n", value.valuename);
737 for (i=0; i<num_values; i++) {
738 d_printf("%s\n", values[i]);
744 printf("%s: unknown type %d\n", value.valuename, value.type);
749 /****************************************************************************
750 ****************************************************************************/
752 static void display_printer_data(const char *v,
753 enum winreg_Type type,
758 union spoolss_PrinterData r;
759 DATA_BLOB blob = data_blob_const(data, length);
762 result = pull_spoolss_PrinterData(talloc_tos(), &blob, &r, type);
763 if (!W_ERROR_IS_OK(result)) {
769 printf("%s: REG_DWORD: 0x%08x\n", v, r.value);
772 printf("%s: REG_SZ: %s\n", v, r.string);
775 char *hex = hex_encode_talloc(NULL,
776 r.binary.data, r.binary.length);
778 printf("%s: REG_BINARY:", v);
780 for (i=0; i<len; i++) {
781 if (hex[i] == '\0') {
794 printf("%s: REG_MULTI_SZ: ", v);
795 for (i=0; r.string_array[i] != NULL; i++) {
796 printf("%s ", r.string_array[i]);
801 printf("%s: unknown type 0x%02x:\n", v, type);
806 /****************************************************************************
807 ****************************************************************************/
809 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
811 int argc, const char **argv)
813 struct policy_handle pol;
816 const char *valuename;
817 enum winreg_Type type;
822 printf("Usage: %s <printername> <valuename>\n", argv[0]);
823 printf("<printername> of . queries print server\n");
828 /* Open a printer handle */
830 if (strncmp(argv[1], ".", sizeof(".")) == 0)
831 fstrcpy(printername, cli->srv_name_slash);
833 slprintf(printername, sizeof(printername)-1, "%s\\%s",
834 cli->srv_name_slash, argv[1]);
836 /* get a printer handle */
838 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
840 SEC_FLAG_MAXIMUM_ALLOWED,
842 if (!W_ERROR_IS_OK(result))
845 /* Get printer info */
847 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
854 if (!W_ERROR_IS_OK(result))
857 /* Display printer data */
859 display_printer_data(valuename, type, data, needed);
862 if (is_valid_policy_hnd(&pol))
863 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
868 /****************************************************************************
869 ****************************************************************************/
871 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
873 int argc, const char **argv)
875 struct policy_handle pol;
879 const char *valuename, *keyname;
881 enum winreg_Type type;
882 uint8_t *data = NULL;
883 uint32_t offered = 0;
887 printf("Usage: %s <printername> <keyname> <valuename>\n",
889 printf("<printername> of . queries print server\n");
895 /* Open a printer handle */
897 if (strncmp(argv[1], ".", sizeof(".")) == 0)
898 fstrcpy(printername, cli->srv_name_slash);
900 slprintf(printername, sizeof(printername)-1, "%s\\%s",
901 cli->srv_name_slash, argv[1]);
903 /* get a printer handle */
905 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
907 SEC_FLAG_MAXIMUM_ALLOWED,
909 if (!W_ERROR_IS_OK(result))
912 /* Get printer info */
914 data = talloc_zero_array(mem_ctx, uint8_t, offered);
919 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
928 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
930 data = talloc_zero_array(mem_ctx, uint8_t, offered);
934 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
945 if (!NT_STATUS_IS_OK(status)) {
949 if (!W_ERROR_IS_OK(result)) {
954 if (!W_ERROR_IS_OK(result))
957 /* Display printer data */
959 display_printer_data(valuename, type, data, needed);
962 if (is_valid_policy_hnd(&pol))
963 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
968 /****************************************************************************
969 ****************************************************************************/
971 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
977 printf("Printer Driver Info 1:\n");
978 printf("\tDriver Name: [%s]\n", r->driver_name);
982 /****************************************************************************
983 ****************************************************************************/
985 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
991 printf("Printer Driver Info 2:\n");
992 printf("\tVersion: [%x]\n", r->version);
993 printf("\tDriver Name: [%s]\n", r->driver_name);
994 printf("\tArchitecture: [%s]\n", r->architecture);
995 printf("\tDriver Path: [%s]\n", r->driver_path);
996 printf("\tDatafile: [%s]\n", r->data_file);
997 printf("\tConfigfile: [%s]\n", r->config_file);
1001 /****************************************************************************
1002 ****************************************************************************/
1004 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1012 printf("Printer Driver Info 3:\n");
1013 printf("\tVersion: [%x]\n", r->version);
1014 printf("\tDriver Name: [%s]\n", r->driver_name);
1015 printf("\tArchitecture: [%s]\n", r->architecture);
1016 printf("\tDriver Path: [%s]\n", r->driver_path);
1017 printf("\tDatafile: [%s]\n", r->data_file);
1018 printf("\tConfigfile: [%s]\n", r->config_file);
1019 printf("\tHelpfile: [%s]\n", r->help_file);
1021 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1022 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1025 printf("\tMonitorname: [%s]\n", r->monitor_name);
1026 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1030 /****************************************************************************
1031 ****************************************************************************/
1033 static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1041 printf("Printer Driver Info 4:\n");
1042 printf("\tVersion: [%x]\n", r->version);
1043 printf("\tDriver Name: [%s]\n", r->driver_name);
1044 printf("\tArchitecture: [%s]\n", r->architecture);
1045 printf("\tDriver Path: [%s]\n", r->driver_path);
1046 printf("\tDatafile: [%s]\n", r->data_file);
1047 printf("\tConfigfile: [%s]\n", r->config_file);
1048 printf("\tHelpfile: [%s]\n", r->help_file);
1050 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1051 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1054 printf("\tMonitorname: [%s]\n", r->monitor_name);
1055 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1057 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1058 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1063 /****************************************************************************
1064 ****************************************************************************/
1066 static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1072 printf("Printer Driver Info 5:\n");
1073 printf("\tVersion: [%x]\n", r->version);
1074 printf("\tDriver Name: [%s]\n", r->driver_name);
1075 printf("\tArchitecture: [%s]\n", r->architecture);
1076 printf("\tDriver Path: [%s]\n", r->driver_path);
1077 printf("\tDatafile: [%s]\n", r->data_file);
1078 printf("\tConfigfile: [%s]\n", r->config_file);
1079 printf("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1080 printf("\tConfig Version: [0x%x]\n", r->config_version);
1081 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1085 /****************************************************************************
1086 ****************************************************************************/
1088 static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1096 printf("Printer Driver Info 6:\n");
1097 printf("\tVersion: [%x]\n", r->version);
1098 printf("\tDriver Name: [%s]\n", r->driver_name);
1099 printf("\tArchitecture: [%s]\n", r->architecture);
1100 printf("\tDriver Path: [%s]\n", r->driver_path);
1101 printf("\tDatafile: [%s]\n", r->data_file);
1102 printf("\tConfigfile: [%s]\n", r->config_file);
1103 printf("\tHelpfile: [%s]\n", r->help_file);
1105 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1106 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1109 printf("\tMonitorname: [%s]\n", r->monitor_name);
1110 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1112 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1113 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1116 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1117 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1118 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1119 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1120 printf("\tHardware ID: [%s]\n", r->hardware_id);
1121 printf("\tProvider: [%s]\n", r->provider);
1126 /****************************************************************************
1127 ****************************************************************************/
1129 static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1137 printf("Printer Driver Info 8:\n");
1138 printf("\tVersion: [%x]\n", r->version);
1139 printf("\tDriver Name: [%s]\n", r->driver_name);
1140 printf("\tArchitecture: [%s]\n", r->architecture);
1141 printf("\tDriver Path: [%s]\n", r->driver_path);
1142 printf("\tDatafile: [%s]\n", r->data_file);
1143 printf("\tConfigfile: [%s]\n", r->config_file);
1144 printf("\tHelpfile: [%s]\n", r->help_file);
1145 printf("\tMonitorname: [%s]\n", r->monitor_name);
1146 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1148 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1149 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1152 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1153 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1156 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1157 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1158 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1159 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1160 printf("\tHardware ID: [%s]\n", r->hardware_id);
1161 printf("\tProvider: [%s]\n", r->provider);
1162 printf("\tPrint Processor: [%s]\n", r->print_processor);
1163 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1164 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1165 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1167 printf("\tInf Path: [%s]\n", r->inf_path);
1168 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1169 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1170 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1172 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1173 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1174 (long long unsigned int)r->min_inbox_driver_ver_version);
1179 /****************************************************************************
1180 ****************************************************************************/
1182 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1183 TALLOC_CTX *mem_ctx,
1184 int argc, const char **argv)
1186 struct policy_handle pol;
1189 const char *printername;
1191 bool success = false;
1192 union spoolss_DriverInfo info;
1193 uint32_t server_major_version;
1194 uint32_t server_minor_version;
1196 if ((argc == 1) || (argc > 3)) {
1197 printf("Usage: %s <printername> [level]\n", argv[0]);
1201 /* get the arguments need to open the printer handle */
1203 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1206 level = atoi(argv[2]);
1209 /* Open a printer handle */
1211 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1215 if (!W_ERROR_IS_OK(werror)) {
1216 printf("Error opening printer handle for %s!\n", printername);
1220 /* loop through and print driver info level for each architecture */
1222 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1224 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1226 archi_table[i].long_archi,
1229 archi_table[i].version,
1232 &server_major_version,
1233 &server_minor_version);
1234 if (!W_ERROR_IS_OK(werror)) {
1238 /* need at least one success */
1242 printf("\n[%s]\n", archi_table[i].long_archi);
1246 display_print_driver1(&info.info1);
1249 display_print_driver2(&info.info2);
1252 display_print_driver3(&info.info3);
1255 display_print_driver4(&info.info4);
1258 display_print_driver5(&info.info5);
1261 display_print_driver6(&info.info6);
1264 display_print_driver8(&info.info8);
1267 printf("unknown info level %d\n", level);
1274 if (is_valid_policy_hnd(&pol)) {
1275 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1285 /****************************************************************************
1286 ****************************************************************************/
1288 static WERROR enum_driver_by_architecture(struct rpc_pipe_client *cli,
1289 TALLOC_CTX *mem_ctx,
1290 const char *architecture,
1295 union spoolss_DriverInfo *info = NULL;
1298 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1299 cli->srv_name_slash,
1306 if (W_ERROR_EQUAL(werror, WERR_INVALID_ENVIRONMENT)) {
1307 printf("Server does not support environment [%s]\n",
1316 if (!W_ERROR_IS_OK(werror)) {
1317 printf("Error getting driver for environment [%s] - %s\n",
1318 architecture, win_errstr(werror));
1322 printf("\n[%s]\n", architecture);
1326 for (j=0; j < count; j++) {
1327 display_print_driver1(&info[j].info1);
1331 for (j=0; j < count; j++) {
1332 display_print_driver2(&info[j].info2);
1336 for (j=0; j < count; j++) {
1337 display_print_driver3(&info[j].info3);
1341 for (j=0; j < count; j++) {
1342 display_print_driver4(&info[j].info4);
1346 for (j=0; j < count; j++) {
1347 display_print_driver5(&info[j].info5);
1351 for (j=0; j < count; j++) {
1352 display_print_driver6(&info[j].info6);
1356 for (j=0; j < count; j++) {
1357 display_print_driver8(&info[j].info8);
1361 printf("unknown info level %d\n", level);
1362 return WERR_UNKNOWN_LEVEL;
1368 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1369 TALLOC_CTX *mem_ctx,
1370 int argc, const char **argv)
1372 WERROR werror = WERR_OK;
1375 const char *architecture = NULL;
1378 printf("Usage: enumdrivers [level] [architecture]\n");
1383 level = atoi(argv[1]);
1387 architecture = argv[2];
1391 return enum_driver_by_architecture(cli, mem_ctx,
1396 /* loop through and print driver info level for each architecture */
1397 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1398 /* check to see if we already asked for this architecture string */
1400 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1404 werror = enum_driver_by_architecture(cli, mem_ctx,
1405 archi_table[i].long_archi,
1407 if (!W_ERROR_IS_OK(werror)) {
1415 /****************************************************************************
1416 ****************************************************************************/
1418 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1420 printf("\tDirectory Name:[%s]\n", r->directory_name);
1423 /****************************************************************************
1424 ****************************************************************************/
1426 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1427 TALLOC_CTX *mem_ctx,
1428 int argc, const char **argv)
1432 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1435 union spoolss_DriverDirectoryInfo info;
1439 printf("Usage: %s [environment]\n", argv[0]);
1443 /* Get the arguments need to open the printer handle */
1449 /* Get the directory. Only use Info level 1 */
1451 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1452 cli->srv_name_slash,
1460 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1462 buffer = data_blob_talloc_zero(mem_ctx, needed);
1464 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1465 cli->srv_name_slash,
1475 if (W_ERROR_IS_OK(result)) {
1476 display_printdriverdir_1(&info.info1);
1482 /****************************************************************************
1483 ****************************************************************************/
1485 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1486 struct spoolss_AddDriverInfo3 *info,
1492 for (i=0; archi_table[i].long_archi != NULL; i++)
1494 if (strcmp(arch, archi_table[i].short_archi) == 0)
1496 info->version = archi_table[i].version;
1497 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1502 if (archi_table[i].long_archi == NULL)
1504 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1511 /**************************************************************************
1512 wrapper for strtok to get the next parameter from a delimited list.
1513 Needed to handle the empty parameter string denoted by "NULL"
1514 *************************************************************************/
1516 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1517 const char *delim, const char **dest,
1522 /* get the next token */
1523 ptr = strtok_r(str, delim, saveptr);
1525 /* a string of 'NULL' is used to represent an empty
1526 parameter because two consecutive delimiters
1527 will not return an empty string. See man strtok(3)
1529 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1534 *dest = talloc_strdup(mem_ctx, ptr);
1540 /********************************************************************************
1541 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1542 string in the form of
1543 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1544 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1545 <Default Data Type>:<Comma Separated list of Files>
1546 *******************************************************************************/
1548 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1553 char *saveptr = NULL;
1554 struct spoolss_StringArray *deps;
1555 const char **file_array = NULL;
1558 /* fill in the UNISTR fields */
1559 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1560 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1561 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1562 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1563 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1564 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1565 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1567 /* <Comma Separated List of Dependent Files> */
1568 /* save the beginning of the string */
1569 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1572 /* begin to strip out each filename */
1573 str = strtok_r(str, ",", &saveptr);
1575 /* no dependent files, we are done */
1580 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1585 while (str != NULL) {
1586 add_string_to_array(deps, str, &file_array, &count);
1587 str = strtok_r(NULL, ",", &saveptr);
1590 deps->string = talloc_zero_array(deps, const char *, count + 1);
1591 if (!deps->string) {
1595 for (i=0; i < count; i++) {
1596 deps->string[i] = file_array[i];
1599 r->dependent_files = deps;
1604 /****************************************************************************
1605 ****************************************************************************/
1607 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1608 TALLOC_CTX *mem_ctx,
1609 int argc, const char **argv)
1614 struct spoolss_AddDriverInfoCtr info_ctr;
1615 struct spoolss_AddDriverInfo3 info3;
1619 /* parse the command arguments */
1620 if (argc != 3 && argc != 4)
1622 printf ("Usage: %s <Environment> \\\n", argv[0]);
1623 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1624 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1625 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1626 printf ("\t[version]\n");
1631 /* Fill in the spoolss_AddDriverInfo3 struct */
1634 arch = cmd_spoolss_get_short_archi(argv[1]);
1636 printf ("Error Unknown architechture [%s]\n", argv[1]);
1637 return WERR_INVALID_PARAM;
1640 set_drv_info_3_env(mem_ctx, &info3, arch);
1642 driver_args = talloc_strdup( mem_ctx, argv[2] );
1643 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1645 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1646 return WERR_INVALID_PARAM;
1649 /* if printer driver version specified, override the default version
1650 * used by the architecture. This allows installation of Windows
1651 * 2000 (version 3) printer drivers. */
1654 info3.version = atoi(argv[3]);
1658 info_ctr.level = level;
1659 info_ctr.info.info3 = &info3;
1661 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1662 cli->srv_name_slash,
1665 if (!NT_STATUS_IS_OK(status)) {
1666 return ntstatus_to_werror(status);
1668 if (W_ERROR_IS_OK(result)) {
1669 printf ("Printer Driver %s successfully installed.\n",
1677 /****************************************************************************
1678 ****************************************************************************/
1680 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1681 TALLOC_CTX *mem_ctx,
1682 int argc, const char **argv)
1685 struct spoolss_SetPrinterInfoCtr info_ctr;
1686 struct spoolss_SetPrinterInfo2 info2;
1688 /* parse the command arguments */
1691 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1695 /* Fill in the DRIVER_INFO_2 struct */
1698 info2.printername = argv[1];
1699 info2.drivername = argv[3];
1700 info2.sharename = argv[2];
1701 info2.portname = argv[4];
1702 info2.comment = "Created by rpcclient";
1703 info2.printprocessor = "winprint";
1704 info2.datatype = "RAW";
1705 info2.devmode_ptr = 0;
1706 info2.secdesc_ptr = 0;
1707 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1709 info2.defaultpriority = 0;
1710 info2.starttime = 0;
1711 info2.untiltime = 0;
1713 /* These three fields must not be used by AddPrinter()
1714 as defined in the MS Platform SDK documentation..
1718 info2.averageppm = 0;
1722 info_ctr.info.info2 = &info2;
1724 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1726 if (W_ERROR_IS_OK(result))
1727 printf ("Printer %s successfully installed.\n", argv[1]);
1732 /****************************************************************************
1733 ****************************************************************************/
1735 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1736 TALLOC_CTX *mem_ctx,
1737 int argc, const char **argv)
1739 struct policy_handle pol;
1743 const char *printername;
1744 union spoolss_PrinterInfo info;
1745 struct spoolss_SetPrinterInfoCtr info_ctr;
1746 struct spoolss_SetPrinterInfo2 info2;
1747 struct spoolss_DevmodeContainer devmode_ctr;
1748 struct sec_desc_buf secdesc_ctr;
1750 ZERO_STRUCT(devmode_ctr);
1751 ZERO_STRUCT(secdesc_ctr);
1753 /* parse the command arguments */
1756 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1760 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1762 /* Get a printer handle */
1764 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1768 if (!W_ERROR_IS_OK(result))
1771 /* Get printer info */
1773 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1778 if (!W_ERROR_IS_OK(result)) {
1779 printf ("Unable to retrieve printer information!\n");
1783 /* Set the printer driver */
1785 info2.servername = info.info2.servername;
1786 info2.printername = info.info2.printername;
1787 info2.sharename = info.info2.sharename;
1788 info2.portname = info.info2.portname;
1789 info2.drivername = argv[2];
1790 info2.comment = info.info2.comment;
1791 info2.location = info.info2.location;
1792 info2.devmode_ptr = 0;
1793 info2.sepfile = info.info2.sepfile;
1794 info2.printprocessor = info.info2.printprocessor;
1795 info2.datatype = info.info2.datatype;
1796 info2.parameters = info.info2.parameters;
1797 info2.secdesc_ptr = 0;
1798 info2.attributes = info.info2.attributes;
1799 info2.priority = info.info2.priority;
1800 info2.defaultpriority = info.info2.defaultpriority;
1801 info2.starttime = info.info2.starttime;
1802 info2.untiltime = info.info2.untiltime;
1803 info2.status = info.info2.status;
1804 info2.cjobs = info.info2.cjobs;
1805 info2.averageppm = info.info2.averageppm;
1808 info_ctr.info.info2 = &info2;
1810 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1817 if (!W_ERROR_IS_OK(result)) {
1818 printf("SetPrinter call failed!\n");
1822 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1827 if (is_valid_policy_hnd(&pol))
1828 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1834 /****************************************************************************
1835 ****************************************************************************/
1837 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1838 TALLOC_CTX *mem_ctx,
1839 int argc, const char **argv)
1841 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1847 const char *arch = NULL;
1848 uint32_t delete_flags = 0;
1850 /* parse the command arguments */
1851 if (argc < 2 || argc > 4) {
1852 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1859 vers = atoi (argv[3]);
1862 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1865 /* delete the driver for all architectures */
1866 for (i=0; archi_table[i].long_archi; i++) {
1868 if (arch && !strequal( archi_table[i].long_archi, arch))
1871 if (vers >= 0 && archi_table[i].version != vers)
1874 /* make the call to remove the driver */
1875 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1876 cli->srv_name_slash,
1877 archi_table[i].long_archi,
1880 archi_table[i].version,
1883 if ( !W_ERROR_IS_OK(result) )
1885 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1886 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1887 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1892 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1893 archi_table[i].long_archi, archi_table[i].version);
1902 /****************************************************************************
1903 ****************************************************************************/
1905 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1906 TALLOC_CTX *mem_ctx,
1907 int argc, const char **argv)
1909 WERROR result = WERR_OK;
1913 /* parse the command arguments */
1915 printf ("Usage: %s <driver>\n", argv[0]);
1919 /* delete the driver for all architectures */
1920 for (i=0; archi_table[i].long_archi; i++) {
1921 /* make the call to remove the driver */
1922 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1923 cli->srv_name_slash,
1924 archi_table[i].long_archi,
1927 if (!NT_STATUS_IS_OK(status)) {
1930 if ( !W_ERROR_IS_OK(result) ) {
1931 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1932 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1933 argv[1], archi_table[i].long_archi,
1937 printf ("Driver %s removed for arch [%s].\n", argv[1],
1938 archi_table[i].long_archi);
1945 /****************************************************************************
1946 ****************************************************************************/
1948 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1949 TALLOC_CTX *mem_ctx,
1950 int argc, const char **argv)
1954 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1957 union spoolss_PrintProcessorDirectoryInfo info;
1960 /* parse the command arguments */
1962 printf ("Usage: %s [environment]\n", argv[0]);
1967 environment = argv[1];
1970 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1971 cli->srv_name_slash,
1979 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1981 buffer = data_blob_talloc_zero(mem_ctx, needed);
1983 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1984 cli->srv_name_slash,
1994 if (W_ERROR_IS_OK(result)) {
1995 printf("%s\n", info.info1.directory_name);
2001 /****************************************************************************
2002 ****************************************************************************/
2004 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2005 int argc, const char **argv)
2007 struct policy_handle handle;
2010 const char *printername;
2011 union spoolss_AddFormInfo info;
2012 struct spoolss_AddFormInfo1 info1;
2013 struct spoolss_AddFormInfo2 info2;
2016 /* Parse the command arguments */
2018 if (argc < 3 || argc > 5) {
2019 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2023 /* Get a printer handle */
2025 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2027 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2031 if (!W_ERROR_IS_OK(werror))
2034 /* Dummy up some values for the form data */
2037 level = atoi(argv[3]);
2042 info1.flags = SPOOLSS_FORM_USER;
2043 info1.form_name = argv[2];
2044 info1.size.width = 100;
2045 info1.size.height = 100;
2046 info1.area.left = 0;
2047 info1.area.top = 10;
2048 info1.area.right = 20;
2049 info1.area.bottom = 30;
2051 info.info1 = &info1;
2055 info2.flags = SPOOLSS_FORM_USER;
2056 info2.form_name = argv[2];
2057 info2.size.width = 100;
2058 info2.size.height = 100;
2059 info2.area.left = 0;
2060 info2.area.top = 10;
2061 info2.area.right = 20;
2062 info2.area.bottom = 30;
2063 info2.keyword = argv[2];
2064 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2065 info2.mui_dll = NULL;
2066 info2.ressource_id = 0;
2067 info2.display_name = argv[2];
2070 info.info2 = &info2;
2078 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2085 if (is_valid_policy_hnd(&handle))
2086 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2091 /****************************************************************************
2092 ****************************************************************************/
2094 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2095 int argc, const char **argv)
2097 struct policy_handle handle;
2100 const char *printername;
2101 union spoolss_AddFormInfo info;
2102 struct spoolss_AddFormInfo1 info1;
2104 /* Parse the command arguments */
2107 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2111 /* Get a printer handle */
2113 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2115 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2117 SEC_FLAG_MAXIMUM_ALLOWED,
2119 if (!W_ERROR_IS_OK(werror))
2122 /* Dummy up some values for the form data */
2124 info1.flags = SPOOLSS_FORM_PRINTER;
2125 info1.size.width = 100;
2126 info1.size.height = 100;
2127 info1.area.left = 0;
2128 info1.area.top = 1000;
2129 info1.area.right = 2000;
2130 info1.area.bottom = 3000;
2131 info1.form_name = argv[2];
2133 info.info1 = &info1;
2137 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2145 if (is_valid_policy_hnd(&handle))
2146 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2151 /****************************************************************************
2152 ****************************************************************************/
2154 static const char *get_form_flag(int form_flag)
2156 switch (form_flag) {
2157 case SPOOLSS_FORM_USER:
2159 case SPOOLSS_FORM_BUILTIN:
2160 return "FORM_BUILTIN";
2161 case SPOOLSS_FORM_PRINTER:
2162 return "FORM_PRINTER";
2168 /****************************************************************************
2169 ****************************************************************************/
2171 static void display_form_info1(struct spoolss_FormInfo1 *r)
2174 "\tflag: %s (%d)\n" \
2175 "\twidth: %d, length: %d\n" \
2176 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2177 r->form_name, get_form_flag(r->flags), r->flags,
2178 r->size.width, r->size.height,
2179 r->area.left, r->area.right,
2180 r->area.top, r->area.bottom);
2183 /****************************************************************************
2184 ****************************************************************************/
2186 static void display_form_info2(struct spoolss_FormInfo2 *r)
2189 "\tflag: %s (%d)\n" \
2190 "\twidth: %d, length: %d\n" \
2191 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2192 r->form_name, get_form_flag(r->flags), r->flags,
2193 r->size.width, r->size.height,
2194 r->area.left, r->area.right,
2195 r->area.top, r->area.bottom);
2196 printf("\tkeyword: %s\n", r->keyword);
2197 printf("\tstring_type: 0x%08x\n", r->string_type);
2198 printf("\tmui_dll: %s\n", r->mui_dll);
2199 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2200 printf("\tdisplay_name: %s\n", r->display_name);
2201 printf("\tlang_id: %d\n", r->lang_id);
2205 /****************************************************************************
2206 ****************************************************************************/
2208 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2209 int argc, const char **argv)
2211 struct policy_handle handle;
2214 const char *printername;
2216 uint32_t offered = 0;
2217 union spoolss_FormInfo info;
2221 /* Parse the command arguments */
2223 if (argc < 3 || argc > 5) {
2224 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2228 /* Get a printer handle */
2230 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2232 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2234 SEC_FLAG_MAXIMUM_ALLOWED,
2236 if (!W_ERROR_IS_OK(werror))
2240 level = atoi(argv[3]);
2245 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2254 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2255 buffer = data_blob_talloc_zero(mem_ctx, needed);
2257 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2268 if (!NT_STATUS_IS_OK(status)) {
2274 display_form_info1(&info.info1);
2277 display_form_info2(&info.info2);
2282 if (is_valid_policy_hnd(&handle))
2283 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2288 /****************************************************************************
2289 ****************************************************************************/
2291 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2292 TALLOC_CTX *mem_ctx, int argc,
2295 struct policy_handle handle;
2298 const char *printername;
2300 /* Parse the command arguments */
2303 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2307 /* Get a printer handle */
2309 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2311 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2313 SEC_FLAG_MAXIMUM_ALLOWED,
2315 if (!W_ERROR_IS_OK(werror))
2318 /* Delete the form */
2320 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2324 if (!NT_STATUS_IS_OK(status)) {
2325 return ntstatus_to_werror(status);
2329 if (is_valid_policy_hnd(&handle))
2330 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2335 /****************************************************************************
2336 ****************************************************************************/
2338 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2339 TALLOC_CTX *mem_ctx, int argc,
2342 struct policy_handle handle;
2344 const char *printername;
2345 uint32_t num_forms, level = 1, i;
2346 union spoolss_FormInfo *forms;
2348 /* Parse the command arguments */
2350 if (argc < 2 || argc > 4) {
2351 printf ("Usage: %s <printer> [level]\n", argv[0]);
2355 /* Get a printer handle */
2357 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2359 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2361 SEC_FLAG_MAXIMUM_ALLOWED,
2363 if (!W_ERROR_IS_OK(werror))
2367 level = atoi(argv[2]);
2370 /* Enumerate forms */
2372 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2379 if (!W_ERROR_IS_OK(werror))
2382 /* Display output */
2384 for (i = 0; i < num_forms; i++) {
2387 display_form_info1(&forms[i].info1);
2390 display_form_info2(&forms[i].info2);
2396 if (is_valid_policy_hnd(&handle))
2397 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2402 /****************************************************************************
2403 ****************************************************************************/
2405 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2406 TALLOC_CTX *mem_ctx,
2407 int argc, const char **argv)
2411 const char *printername;
2412 struct policy_handle pol;
2413 union spoolss_PrinterInfo info;
2414 enum winreg_Type type;
2415 union spoolss_PrinterData data;
2418 /* parse the command arguments */
2420 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2421 " <value> <data>\n",
2423 result = WERR_INVALID_PARAM;
2427 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2431 if (strequal(argv[2], "string")) {
2435 if (strequal(argv[2], "binary")) {
2439 if (strequal(argv[2], "dword")) {
2443 if (strequal(argv[2], "multistring")) {
2444 type = REG_MULTI_SZ;
2447 if (type == REG_NONE) {
2448 printf("Unknown data type: %s\n", argv[2]);
2449 result = WERR_INVALID_PARAM;
2453 /* get a printer handle */
2455 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2457 SEC_FLAG_MAXIMUM_ALLOWED,
2459 if (!W_ERROR_IS_OK(result)) {
2463 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2468 if (!W_ERROR_IS_OK(result)) {
2472 printf("%s\n", current_timestring(mem_ctx, true));
2473 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2475 /* Set the printer data */
2479 data.string = talloc_strdup(mem_ctx, argv[4]);
2480 W_ERROR_HAVE_NO_MEMORY(data.string);
2483 data.value = strtoul(argv[4], NULL, 10);
2486 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2488 case REG_MULTI_SZ: {
2490 const char **strings = NULL;
2492 for (i=4; i<argc; i++) {
2493 if (strcmp(argv[i], "NULL") == 0) {
2496 if (!add_string_to_array(mem_ctx, argv[i],
2499 result = WERR_NOMEM;
2503 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2504 if (!data.string_array) {
2505 result = WERR_NOMEM;
2508 for (i=0; i < num_strings; i++) {
2509 data.string_array[i] = strings[i];
2514 printf("Unknown data type: %s\n", argv[2]);
2515 result = WERR_INVALID_PARAM;
2519 result = push_spoolss_PrinterData(mem_ctx, &blob, type, &data);
2520 if (!W_ERROR_IS_OK(result)) {
2524 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2526 argv[3], /* value_name */
2531 if (!W_ERROR_IS_OK(result)) {
2532 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2535 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2537 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2542 if (!W_ERROR_IS_OK(result)) {
2546 printf("%s\n", current_timestring(mem_ctx, true));
2547 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2551 if (is_valid_policy_hnd(&pol)) {
2552 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2558 /****************************************************************************
2559 ****************************************************************************/
2561 static void display_job_info1(struct spoolss_JobInfo1 *r)
2563 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2564 r->user_name, r->document_name, r->text_status, r->pages_printed,
2568 /****************************************************************************
2569 ****************************************************************************/
2571 static void display_job_info2(struct spoolss_JobInfo2 *r)
2573 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2574 r->position, r->job_id,
2575 r->user_name, r->document_name, r->text_status, r->pages_printed,
2576 r->total_pages, r->size);
2579 /****************************************************************************
2580 ****************************************************************************/
2582 static void display_job_info3(struct spoolss_JobInfo3 *r)
2584 printf("jobid[%d], next_jobid[%d]\n",
2585 r->job_id, r->next_job_id);
2588 /****************************************************************************
2589 ****************************************************************************/
2591 static void display_job_info4(struct spoolss_JobInfo4 *r)
2593 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2594 r->position, r->job_id,
2595 r->user_name, r->document_name, r->text_status, r->pages_printed,
2596 r->total_pages, r->size, r->size_high);
2599 /****************************************************************************
2600 ****************************************************************************/
2602 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2603 TALLOC_CTX *mem_ctx, int argc,
2607 uint32_t level = 1, count, i;
2608 const char *printername;
2609 struct policy_handle hnd;
2610 union spoolss_JobInfo *info;
2612 if (argc < 2 || argc > 3) {
2613 printf("Usage: %s printername [level]\n", argv[0]);
2618 level = atoi(argv[2]);
2621 /* Open printer handle */
2623 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2625 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2627 SEC_FLAG_MAXIMUM_ALLOWED,
2629 if (!W_ERROR_IS_OK(result))
2632 /* Enumerate ports */
2634 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2642 if (!W_ERROR_IS_OK(result)) {
2646 for (i = 0; i < count; i++) {
2649 display_job_info1(&info[i].info1);
2652 display_job_info2(&info[i].info2);
2655 d_printf("unknown info level %d\n", level);
2661 if (is_valid_policy_hnd(&hnd)) {
2662 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2668 /****************************************************************************
2669 ****************************************************************************/
2671 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2672 TALLOC_CTX *mem_ctx, int argc,
2676 const char *printername;
2677 struct policy_handle hnd;
2680 union spoolss_JobInfo info;
2682 if (argc < 3 || argc > 4) {
2683 printf("Usage: %s printername job_id [level]\n", argv[0]);
2687 job_id = atoi(argv[2]);
2690 level = atoi(argv[3]);
2693 /* Open printer handle */
2695 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2697 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2699 SEC_FLAG_MAXIMUM_ALLOWED,
2701 if (!W_ERROR_IS_OK(result)) {
2705 /* Enumerate ports */
2707 result = rpccli_spoolss_getjob(cli, mem_ctx,
2714 if (!W_ERROR_IS_OK(result)) {
2720 display_job_info1(&info.info1);
2723 display_job_info2(&info.info2);
2726 display_job_info3(&info.info3);
2729 display_job_info4(&info.info4);
2732 d_printf("unknown info level %d\n", level);
2737 if (is_valid_policy_hnd(&hnd)) {
2738 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2744 /****************************************************************************
2745 ****************************************************************************/
2747 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2748 TALLOC_CTX *mem_ctx, int argc,
2753 const char *printername;
2754 struct policy_handle hnd;
2756 enum spoolss_JobControl command;
2759 printf("Usage: %s printername job_id command\n", argv[0]);
2763 job_id = atoi(argv[2]);
2764 command = atoi(argv[3]);
2766 /* Open printer handle */
2768 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2770 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2772 SEC_FLAG_MAXIMUM_ALLOWED,
2774 if (!W_ERROR_IS_OK(result)) {
2780 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2787 if (!W_ERROR_IS_OK(result)) {
2792 if (is_valid_policy_hnd(&hnd)) {
2793 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2799 /****************************************************************************
2800 ****************************************************************************/
2802 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2803 TALLOC_CTX *mem_ctx, int argc,
2809 const char *printername;
2810 struct policy_handle hnd;
2811 uint32_t value_offered = 0;
2812 const char *value_name = NULL;
2813 uint32_t value_needed;
2814 enum winreg_Type type;
2815 uint8_t *data = NULL;
2816 uint32_t data_offered = 0;
2817 uint32_t data_needed;
2820 printf("Usage: %s printername\n", argv[0]);
2824 /* Open printer handle */
2826 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2828 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2830 SEC_FLAG_MAXIMUM_ALLOWED,
2832 if (!W_ERROR_IS_OK(result)) {
2836 /* Enumerate data */
2838 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2850 data_offered = data_needed;
2851 value_offered = value_needed;
2852 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2853 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2855 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2857 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2868 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2870 fstrcpy(v.valuename, value_name);
2872 v.size = data_offered;
2874 display_reg_value(v);
2878 if (W_ERROR_V(result) == ERRnomoreitems) {
2879 result = W_ERROR(ERRsuccess);
2883 if (is_valid_policy_hnd(&hnd)) {
2884 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2890 /****************************************************************************
2891 ****************************************************************************/
2893 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2894 TALLOC_CTX *mem_ctx, int argc,
2899 const char *printername;
2900 struct policy_handle hnd;
2902 struct spoolss_PrinterEnumValues *info;
2905 printf("Usage: %s printername <keyname>\n", argv[0]);
2909 /* Open printer handle */
2911 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2913 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2915 SEC_FLAG_MAXIMUM_ALLOWED,
2917 if (!W_ERROR_IS_OK(result)) {
2921 /* Enumerate subkeys */
2923 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
2929 if (!W_ERROR_IS_OK(result)) {
2933 for (i=0; i < count; i++) {
2934 display_printer_data(info[i].value_name,
2937 info[i].data->length);
2941 if (is_valid_policy_hnd(&hnd)) {
2942 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2948 /****************************************************************************
2949 ****************************************************************************/
2951 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
2952 TALLOC_CTX *mem_ctx, int argc,
2956 const char *printername;
2957 const char *keyname = NULL;
2958 struct policy_handle hnd;
2959 const char **key_buffer = NULL;
2962 if (argc < 2 || argc > 3) {
2963 printf("Usage: %s printername [keyname]\n", argv[0]);
2973 /* Open printer handle */
2975 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2977 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2979 SEC_FLAG_MAXIMUM_ALLOWED,
2981 if (!W_ERROR_IS_OK(result)) {
2985 /* Enumerate subkeys */
2987 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
2993 if (!W_ERROR_IS_OK(result)) {
2997 for (i=0; key_buffer && key_buffer[i]; i++) {
2998 printf("%s\n", key_buffer[i]);
3003 if (is_valid_policy_hnd(&hnd)) {
3004 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3010 /****************************************************************************
3011 ****************************************************************************/
3013 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
3014 TALLOC_CTX *mem_ctx, int argc,
3017 const char *printername;
3018 const char *clientname;
3019 struct policy_handle hnd;
3022 struct spoolss_NotifyOption option;
3025 printf("Usage: %s printername\n", argv[0]);
3032 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3034 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3036 SEC_FLAG_MAXIMUM_ALLOWED,
3038 if (!W_ERROR_IS_OK(result)) {
3039 printf("Error opening %s\n", argv[1]);
3043 /* Create spool options */
3048 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3049 if (option.types == NULL) {
3050 result = WERR_NOMEM;
3054 option.types[0].type = PRINTER_NOTIFY_TYPE;
3055 option.types[0].count = 1;
3056 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3057 if (option.types[0].fields == NULL) {
3058 result = WERR_NOMEM;
3061 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3063 option.types[1].type = JOB_NOTIFY_TYPE;
3064 option.types[1].count = 1;
3065 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3066 if (option.types[1].fields == NULL) {
3067 result = WERR_NOMEM;
3070 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3072 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3074 result = WERR_NOMEM;
3080 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3088 if (!W_ERROR_IS_OK(result)) {
3089 printf("Error rffpcnex %s\n", argv[1]);
3094 if (is_valid_policy_hnd(&hnd))
3095 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3100 /****************************************************************************
3101 ****************************************************************************/
3103 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3104 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3106 union spoolss_PrinterInfo info1, info2;
3108 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3110 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3111 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3116 if ( !W_ERROR_IS_OK(werror) ) {
3117 printf("failed (%s)\n", win_errstr(werror));
3118 talloc_destroy(mem_ctx);
3123 printf("Retrieving printer properties for %s...", cli2->desthost);
3124 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3129 if ( !W_ERROR_IS_OK(werror) ) {
3130 printf("failed (%s)\n", win_errstr(werror));
3131 talloc_destroy(mem_ctx);
3136 talloc_destroy(mem_ctx);
3141 /****************************************************************************
3142 ****************************************************************************/
3144 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3145 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3147 union spoolss_PrinterInfo info1, info2;
3149 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3150 SEC_DESC *sd1, *sd2;
3154 printf("Retrieving printer security for %s...", cli1->desthost);
3155 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3160 if ( !W_ERROR_IS_OK(werror) ) {
3161 printf("failed (%s)\n", win_errstr(werror));
3167 printf("Retrieving printer security for %s...", cli2->desthost);
3168 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3173 if ( !W_ERROR_IS_OK(werror) ) {
3174 printf("failed (%s)\n", win_errstr(werror));
3183 sd1 = info1.info3.secdesc;
3184 sd2 = info2.info3.secdesc;
3186 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3187 printf("NULL secdesc!\n");
3192 if (!sec_desc_equal( sd1, sd2 ) ) {
3193 printf("Security Descriptors *not* equal!\n");
3198 printf("Security descriptors match\n");
3201 talloc_destroy(mem_ctx);
3206 /****************************************************************************
3207 ****************************************************************************/
3209 extern struct user_auth_info *rpcclient_auth_info;
3211 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3212 TALLOC_CTX *mem_ctx, int argc,
3215 const char *printername;
3216 char *printername_path = NULL;
3217 struct cli_state *cli_server2 = NULL;
3218 struct rpc_pipe_client *cli2 = NULL;
3219 struct policy_handle hPrinter1, hPrinter2;
3224 printf("Usage: %s <printer> <server>\n", argv[0]);
3228 printername = argv[1];
3230 /* first get the connection to the remote server */
3232 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3235 get_cmdline_auth_info_username(rpcclient_auth_info),
3237 get_cmdline_auth_info_password(rpcclient_auth_info),
3238 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3239 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3241 if ( !NT_STATUS_IS_OK(nt_status) )
3242 return WERR_GENERAL_FAILURE;
3244 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3246 if (!NT_STATUS_IS_OK(nt_status)) {
3247 printf("failed to open spoolss pipe on server %s (%s)\n",
3248 argv[2], nt_errstr(nt_status));
3249 return WERR_GENERAL_FAILURE;
3252 /* now open up both printers */
3254 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3256 printf("Opening %s...", printername_path);
3258 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3262 if ( !W_ERROR_IS_OK(werror) ) {
3263 printf("failed (%s)\n", win_errstr(werror));
3268 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3270 printf("Opening %s...", printername_path);
3271 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3275 if ( !W_ERROR_IS_OK(werror) ) {
3276 printf("failed (%s)\n", win_errstr(werror));
3281 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3282 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3284 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3291 printf("Closing printers...");
3292 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3293 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3296 /* close the second remote connection */
3298 cli_shutdown( cli_server2 );
3302 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3304 printf("print_processor_name: %s\n", r->print_processor_name);
3307 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3308 TALLOC_CTX *mem_ctx, int argc,
3312 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3313 uint32_t num_procs, level = 1, i;
3314 union spoolss_PrintProcessorInfo *procs;
3316 /* Parse the command arguments */
3318 if (argc < 1 || argc > 4) {
3319 printf ("Usage: %s [environment] [level]\n", argv[0]);
3324 environment = argv[1];
3328 level = atoi(argv[2]);
3331 /* Enumerate Print Processors */
3333 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3334 cli->srv_name_slash,
3340 if (!W_ERROR_IS_OK(werror))
3343 /* Display output */
3345 for (i = 0; i < num_procs; i++) {
3348 display_proc_info1(&procs[i].info1);
3357 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3359 printf("name_array: %s\n", r->name_array);
3362 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3363 TALLOC_CTX *mem_ctx, int argc,
3367 const char *print_processor_name = "winprint";
3368 uint32_t num_procs, level = 1, i;
3369 union spoolss_PrintProcDataTypesInfo *procs;
3371 /* Parse the command arguments */
3373 if (argc < 1 || argc > 4) {
3374 printf ("Usage: %s [environment] [level]\n", argv[0]);
3379 print_processor_name = argv[1];
3383 level = atoi(argv[2]);
3386 /* Enumerate Print Processor Data Types */
3388 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3389 cli->srv_name_slash,
3390 print_processor_name,
3395 if (!W_ERROR_IS_OK(werror))
3398 /* Display output */
3400 for (i = 0; i < num_procs; i++) {
3403 display_proc_data_types_info1(&procs[i].info1);
3412 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3414 printf("monitor_name: %s\n", r->monitor_name);
3417 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3419 printf("monitor_name: %s\n", r->monitor_name);
3420 printf("environment: %s\n", r->environment);
3421 printf("dll_name: %s\n", r->dll_name);
3424 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3425 TALLOC_CTX *mem_ctx, int argc,
3429 uint32_t count, level = 1, i;
3430 union spoolss_MonitorInfo *info;
3432 /* Parse the command arguments */
3435 printf("Usage: %s [level]\n", argv[0]);
3440 level = atoi(argv[1]);
3443 /* Enumerate Print Monitors */
3445 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3446 cli->srv_name_slash,
3451 if (!W_ERROR_IS_OK(werror)) {
3455 /* Display output */
3457 for (i = 0; i < count; i++) {
3460 display_monitor1(&info[i].info1);
3463 display_monitor2(&info[i].info2);
3472 /* List of commands exported by this module */
3473 struct cmd_set spoolss_commands[] = {
3477 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3478 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3479 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3480 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3481 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3482 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3483 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3484 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3485 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3486 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3487 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3488 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3489 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3490 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3491 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3492 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3493 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3494 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3495 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3496 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3497 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3498 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3499 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3500 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3501 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3502 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3503 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3504 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3505 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3506 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3507 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3508 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3509 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3510 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },