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++) {
1923 /* make the call to remove the driver */
1924 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1925 cli->srv_name_slash,
1926 archi_table[i].long_archi,
1929 if (!NT_STATUS_IS_OK(status)) {
1930 if (W_ERROR_IS_OK(result)) {
1931 result = ntstatus_to_werror(status);
1934 if ( !W_ERROR_IS_OK(result) ) {
1935 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1936 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1937 argv[1], archi_table[i].long_archi,
1941 printf ("Driver %s removed for arch [%s].\n", argv[1],
1942 archi_table[i].long_archi);
1949 /****************************************************************************
1950 ****************************************************************************/
1952 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1953 TALLOC_CTX *mem_ctx,
1954 int argc, const char **argv)
1958 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1961 union spoolss_PrintProcessorDirectoryInfo info;
1964 /* parse the command arguments */
1966 printf ("Usage: %s [environment]\n", argv[0]);
1971 environment = argv[1];
1974 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1975 cli->srv_name_slash,
1983 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1985 buffer = data_blob_talloc_zero(mem_ctx, needed);
1987 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1988 cli->srv_name_slash,
1998 if (W_ERROR_IS_OK(result)) {
1999 printf("%s\n", info.info1.directory_name);
2005 /****************************************************************************
2006 ****************************************************************************/
2008 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2009 int argc, const char **argv)
2011 struct policy_handle handle;
2014 const char *printername;
2015 union spoolss_AddFormInfo info;
2016 struct spoolss_AddFormInfo1 info1;
2017 struct spoolss_AddFormInfo2 info2;
2020 /* Parse the command arguments */
2022 if (argc < 3 || argc > 5) {
2023 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2027 /* Get a printer handle */
2029 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2031 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2035 if (!W_ERROR_IS_OK(werror))
2038 /* Dummy up some values for the form data */
2041 level = atoi(argv[3]);
2046 info1.flags = SPOOLSS_FORM_USER;
2047 info1.form_name = argv[2];
2048 info1.size.width = 100;
2049 info1.size.height = 100;
2050 info1.area.left = 0;
2051 info1.area.top = 10;
2052 info1.area.right = 20;
2053 info1.area.bottom = 30;
2055 info.info1 = &info1;
2059 info2.flags = SPOOLSS_FORM_USER;
2060 info2.form_name = argv[2];
2061 info2.size.width = 100;
2062 info2.size.height = 100;
2063 info2.area.left = 0;
2064 info2.area.top = 10;
2065 info2.area.right = 20;
2066 info2.area.bottom = 30;
2067 info2.keyword = argv[2];
2068 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2069 info2.mui_dll = NULL;
2070 info2.ressource_id = 0;
2071 info2.display_name = argv[2];
2074 info.info2 = &info2;
2082 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2089 if (is_valid_policy_hnd(&handle))
2090 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2095 /****************************************************************************
2096 ****************************************************************************/
2098 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2099 int argc, const char **argv)
2101 struct policy_handle handle;
2104 const char *printername;
2105 union spoolss_AddFormInfo info;
2106 struct spoolss_AddFormInfo1 info1;
2108 /* Parse the command arguments */
2111 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2115 /* Get a printer handle */
2117 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2119 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2121 SEC_FLAG_MAXIMUM_ALLOWED,
2123 if (!W_ERROR_IS_OK(werror))
2126 /* Dummy up some values for the form data */
2128 info1.flags = SPOOLSS_FORM_PRINTER;
2129 info1.size.width = 100;
2130 info1.size.height = 100;
2131 info1.area.left = 0;
2132 info1.area.top = 1000;
2133 info1.area.right = 2000;
2134 info1.area.bottom = 3000;
2135 info1.form_name = argv[2];
2137 info.info1 = &info1;
2141 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2149 if (is_valid_policy_hnd(&handle))
2150 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2155 /****************************************************************************
2156 ****************************************************************************/
2158 static const char *get_form_flag(int form_flag)
2160 switch (form_flag) {
2161 case SPOOLSS_FORM_USER:
2163 case SPOOLSS_FORM_BUILTIN:
2164 return "FORM_BUILTIN";
2165 case SPOOLSS_FORM_PRINTER:
2166 return "FORM_PRINTER";
2172 /****************************************************************************
2173 ****************************************************************************/
2175 static void display_form_info1(struct spoolss_FormInfo1 *r)
2178 "\tflag: %s (%d)\n" \
2179 "\twidth: %d, length: %d\n" \
2180 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2181 r->form_name, get_form_flag(r->flags), r->flags,
2182 r->size.width, r->size.height,
2183 r->area.left, r->area.right,
2184 r->area.top, r->area.bottom);
2187 /****************************************************************************
2188 ****************************************************************************/
2190 static void display_form_info2(struct spoolss_FormInfo2 *r)
2193 "\tflag: %s (%d)\n" \
2194 "\twidth: %d, length: %d\n" \
2195 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2196 r->form_name, get_form_flag(r->flags), r->flags,
2197 r->size.width, r->size.height,
2198 r->area.left, r->area.right,
2199 r->area.top, r->area.bottom);
2200 printf("\tkeyword: %s\n", r->keyword);
2201 printf("\tstring_type: 0x%08x\n", r->string_type);
2202 printf("\tmui_dll: %s\n", r->mui_dll);
2203 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2204 printf("\tdisplay_name: %s\n", r->display_name);
2205 printf("\tlang_id: %d\n", r->lang_id);
2209 /****************************************************************************
2210 ****************************************************************************/
2212 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2213 int argc, const char **argv)
2215 struct policy_handle handle;
2218 const char *printername;
2220 uint32_t offered = 0;
2221 union spoolss_FormInfo info;
2225 /* Parse the command arguments */
2227 if (argc < 3 || argc > 5) {
2228 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2232 /* Get a printer handle */
2234 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2236 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2238 SEC_FLAG_MAXIMUM_ALLOWED,
2240 if (!W_ERROR_IS_OK(werror))
2244 level = atoi(argv[3]);
2249 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2258 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2259 buffer = data_blob_talloc_zero(mem_ctx, needed);
2261 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2272 if (!NT_STATUS_IS_OK(status)) {
2278 display_form_info1(&info.info1);
2281 display_form_info2(&info.info2);
2286 if (is_valid_policy_hnd(&handle))
2287 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2292 /****************************************************************************
2293 ****************************************************************************/
2295 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2296 TALLOC_CTX *mem_ctx, int argc,
2299 struct policy_handle handle;
2302 const char *printername;
2304 /* Parse the command arguments */
2307 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2311 /* Get a printer handle */
2313 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2315 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2317 SEC_FLAG_MAXIMUM_ALLOWED,
2319 if (!W_ERROR_IS_OK(werror))
2322 /* Delete the form */
2324 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2328 if (!NT_STATUS_IS_OK(status)) {
2329 return ntstatus_to_werror(status);
2333 if (is_valid_policy_hnd(&handle))
2334 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2339 /****************************************************************************
2340 ****************************************************************************/
2342 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2343 TALLOC_CTX *mem_ctx, int argc,
2346 struct policy_handle handle;
2348 const char *printername;
2349 uint32_t num_forms, level = 1, i;
2350 union spoolss_FormInfo *forms;
2352 /* Parse the command arguments */
2354 if (argc < 2 || argc > 4) {
2355 printf ("Usage: %s <printer> [level]\n", argv[0]);
2359 /* Get a printer handle */
2361 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2363 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2365 SEC_FLAG_MAXIMUM_ALLOWED,
2367 if (!W_ERROR_IS_OK(werror))
2371 level = atoi(argv[2]);
2374 /* Enumerate forms */
2376 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2383 if (!W_ERROR_IS_OK(werror))
2386 /* Display output */
2388 for (i = 0; i < num_forms; i++) {
2391 display_form_info1(&forms[i].info1);
2394 display_form_info2(&forms[i].info2);
2400 if (is_valid_policy_hnd(&handle))
2401 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2406 /****************************************************************************
2407 ****************************************************************************/
2409 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2410 TALLOC_CTX *mem_ctx,
2411 int argc, const char **argv)
2415 const char *printername;
2416 struct policy_handle pol;
2417 union spoolss_PrinterInfo info;
2418 enum winreg_Type type;
2419 union spoolss_PrinterData data;
2422 /* parse the command arguments */
2424 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2425 " <value> <data>\n",
2427 result = WERR_INVALID_PARAM;
2431 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2435 if (strequal(argv[2], "string")) {
2439 if (strequal(argv[2], "binary")) {
2443 if (strequal(argv[2], "dword")) {
2447 if (strequal(argv[2], "multistring")) {
2448 type = REG_MULTI_SZ;
2451 if (type == REG_NONE) {
2452 printf("Unknown data type: %s\n", argv[2]);
2453 result = WERR_INVALID_PARAM;
2457 /* get a printer handle */
2459 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2461 SEC_FLAG_MAXIMUM_ALLOWED,
2463 if (!W_ERROR_IS_OK(result)) {
2467 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2472 if (!W_ERROR_IS_OK(result)) {
2476 printf("%s\n", current_timestring(mem_ctx, true));
2477 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2479 /* Set the printer data */
2483 data.string = talloc_strdup(mem_ctx, argv[4]);
2484 W_ERROR_HAVE_NO_MEMORY(data.string);
2487 data.value = strtoul(argv[4], NULL, 10);
2490 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2492 case REG_MULTI_SZ: {
2494 const char **strings = NULL;
2496 for (i=4; i<argc; i++) {
2497 if (strcmp(argv[i], "NULL") == 0) {
2500 if (!add_string_to_array(mem_ctx, argv[i],
2503 result = WERR_NOMEM;
2507 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2508 if (!data.string_array) {
2509 result = WERR_NOMEM;
2512 for (i=0; i < num_strings; i++) {
2513 data.string_array[i] = strings[i];
2518 printf("Unknown data type: %s\n", argv[2]);
2519 result = WERR_INVALID_PARAM;
2523 result = push_spoolss_PrinterData(mem_ctx, &blob, type, &data);
2524 if (!W_ERROR_IS_OK(result)) {
2528 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2530 argv[3], /* value_name */
2535 if (!W_ERROR_IS_OK(result)) {
2536 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2539 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2541 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2546 if (!W_ERROR_IS_OK(result)) {
2550 printf("%s\n", current_timestring(mem_ctx, true));
2551 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2555 if (is_valid_policy_hnd(&pol)) {
2556 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2562 /****************************************************************************
2563 ****************************************************************************/
2565 static void display_job_info1(struct spoolss_JobInfo1 *r)
2567 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2568 r->user_name, r->document_name, r->text_status, r->pages_printed,
2572 /****************************************************************************
2573 ****************************************************************************/
2575 static void display_job_info2(struct spoolss_JobInfo2 *r)
2577 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2578 r->position, r->job_id,
2579 r->user_name, r->document_name, r->text_status, r->pages_printed,
2580 r->total_pages, r->size);
2583 /****************************************************************************
2584 ****************************************************************************/
2586 static void display_job_info3(struct spoolss_JobInfo3 *r)
2588 printf("jobid[%d], next_jobid[%d]\n",
2589 r->job_id, r->next_job_id);
2592 /****************************************************************************
2593 ****************************************************************************/
2595 static void display_job_info4(struct spoolss_JobInfo4 *r)
2597 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2598 r->position, r->job_id,
2599 r->user_name, r->document_name, r->text_status, r->pages_printed,
2600 r->total_pages, r->size, r->size_high);
2603 /****************************************************************************
2604 ****************************************************************************/
2606 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2607 TALLOC_CTX *mem_ctx, int argc,
2611 uint32_t level = 1, count, i;
2612 const char *printername;
2613 struct policy_handle hnd;
2614 union spoolss_JobInfo *info;
2616 if (argc < 2 || argc > 3) {
2617 printf("Usage: %s printername [level]\n", argv[0]);
2622 level = atoi(argv[2]);
2625 /* Open printer handle */
2627 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2629 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2631 SEC_FLAG_MAXIMUM_ALLOWED,
2633 if (!W_ERROR_IS_OK(result))
2636 /* Enumerate ports */
2638 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2646 if (!W_ERROR_IS_OK(result)) {
2650 for (i = 0; i < count; i++) {
2653 display_job_info1(&info[i].info1);
2656 display_job_info2(&info[i].info2);
2659 d_printf("unknown info level %d\n", level);
2665 if (is_valid_policy_hnd(&hnd)) {
2666 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2672 /****************************************************************************
2673 ****************************************************************************/
2675 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2676 TALLOC_CTX *mem_ctx, int argc,
2680 const char *printername;
2681 struct policy_handle hnd;
2684 union spoolss_JobInfo info;
2686 if (argc < 3 || argc > 4) {
2687 printf("Usage: %s printername job_id [level]\n", argv[0]);
2691 job_id = atoi(argv[2]);
2694 level = atoi(argv[3]);
2697 /* Open printer handle */
2699 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2701 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2703 SEC_FLAG_MAXIMUM_ALLOWED,
2705 if (!W_ERROR_IS_OK(result)) {
2709 /* Enumerate ports */
2711 result = rpccli_spoolss_getjob(cli, mem_ctx,
2718 if (!W_ERROR_IS_OK(result)) {
2724 display_job_info1(&info.info1);
2727 display_job_info2(&info.info2);
2730 display_job_info3(&info.info3);
2733 display_job_info4(&info.info4);
2736 d_printf("unknown info level %d\n", level);
2741 if (is_valid_policy_hnd(&hnd)) {
2742 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2748 /****************************************************************************
2749 ****************************************************************************/
2751 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2752 TALLOC_CTX *mem_ctx, int argc,
2757 const char *printername;
2758 struct policy_handle hnd;
2760 enum spoolss_JobControl command;
2763 printf("Usage: %s printername job_id command\n", argv[0]);
2767 job_id = atoi(argv[2]);
2768 command = atoi(argv[3]);
2770 /* Open printer handle */
2772 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2774 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2776 SEC_FLAG_MAXIMUM_ALLOWED,
2778 if (!W_ERROR_IS_OK(result)) {
2784 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2791 if (!W_ERROR_IS_OK(result)) {
2796 if (is_valid_policy_hnd(&hnd)) {
2797 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2803 /****************************************************************************
2804 ****************************************************************************/
2806 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2807 TALLOC_CTX *mem_ctx, int argc,
2813 const char *printername;
2814 struct policy_handle hnd;
2815 uint32_t value_offered = 0;
2816 const char *value_name = NULL;
2817 uint32_t value_needed;
2818 enum winreg_Type type;
2819 uint8_t *data = NULL;
2820 uint32_t data_offered = 0;
2821 uint32_t data_needed;
2824 printf("Usage: %s printername\n", argv[0]);
2828 /* Open printer handle */
2830 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2832 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2834 SEC_FLAG_MAXIMUM_ALLOWED,
2836 if (!W_ERROR_IS_OK(result)) {
2840 /* Enumerate data */
2842 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2854 data_offered = data_needed;
2855 value_offered = value_needed;
2856 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2857 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2859 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2861 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2872 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2874 fstrcpy(v.valuename, value_name);
2876 v.size = data_offered;
2878 display_reg_value(v);
2882 if (W_ERROR_V(result) == ERRnomoreitems) {
2883 result = W_ERROR(ERRsuccess);
2887 if (is_valid_policy_hnd(&hnd)) {
2888 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2894 /****************************************************************************
2895 ****************************************************************************/
2897 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2898 TALLOC_CTX *mem_ctx, int argc,
2903 const char *printername;
2904 struct policy_handle hnd;
2906 struct spoolss_PrinterEnumValues *info;
2909 printf("Usage: %s printername <keyname>\n", argv[0]);
2913 /* Open printer handle */
2915 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2917 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2919 SEC_FLAG_MAXIMUM_ALLOWED,
2921 if (!W_ERROR_IS_OK(result)) {
2925 /* Enumerate subkeys */
2927 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
2933 if (!W_ERROR_IS_OK(result)) {
2937 for (i=0; i < count; i++) {
2938 display_printer_data(info[i].value_name,
2941 info[i].data->length);
2945 if (is_valid_policy_hnd(&hnd)) {
2946 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2952 /****************************************************************************
2953 ****************************************************************************/
2955 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
2956 TALLOC_CTX *mem_ctx, int argc,
2960 const char *printername;
2961 const char *keyname = NULL;
2962 struct policy_handle hnd;
2963 const char **key_buffer = NULL;
2966 if (argc < 2 || argc > 3) {
2967 printf("Usage: %s printername [keyname]\n", argv[0]);
2977 /* Open printer handle */
2979 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2981 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2983 SEC_FLAG_MAXIMUM_ALLOWED,
2985 if (!W_ERROR_IS_OK(result)) {
2989 /* Enumerate subkeys */
2991 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
2997 if (!W_ERROR_IS_OK(result)) {
3001 for (i=0; key_buffer && key_buffer[i]; i++) {
3002 printf("%s\n", key_buffer[i]);
3007 if (is_valid_policy_hnd(&hnd)) {
3008 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3014 /****************************************************************************
3015 ****************************************************************************/
3017 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
3018 TALLOC_CTX *mem_ctx, int argc,
3021 const char *printername;
3022 const char *clientname;
3023 struct policy_handle hnd;
3026 struct spoolss_NotifyOption option;
3029 printf("Usage: %s printername\n", argv[0]);
3036 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3038 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3040 SEC_FLAG_MAXIMUM_ALLOWED,
3042 if (!W_ERROR_IS_OK(result)) {
3043 printf("Error opening %s\n", argv[1]);
3047 /* Create spool options */
3052 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3053 if (option.types == NULL) {
3054 result = WERR_NOMEM;
3058 option.types[0].type = PRINTER_NOTIFY_TYPE;
3059 option.types[0].count = 1;
3060 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3061 if (option.types[0].fields == NULL) {
3062 result = WERR_NOMEM;
3065 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3067 option.types[1].type = JOB_NOTIFY_TYPE;
3068 option.types[1].count = 1;
3069 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3070 if (option.types[1].fields == NULL) {
3071 result = WERR_NOMEM;
3074 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3076 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3078 result = WERR_NOMEM;
3084 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3092 if (!W_ERROR_IS_OK(result)) {
3093 printf("Error rffpcnex %s\n", argv[1]);
3098 if (is_valid_policy_hnd(&hnd))
3099 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3104 /****************************************************************************
3105 ****************************************************************************/
3107 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3108 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3110 union spoolss_PrinterInfo info1, info2;
3112 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3114 printf("Retrieving printer propertiesfor %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));
3122 talloc_destroy(mem_ctx);
3127 printf("Retrieving printer properties 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));
3135 talloc_destroy(mem_ctx);
3140 talloc_destroy(mem_ctx);
3145 /****************************************************************************
3146 ****************************************************************************/
3148 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3149 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3151 union spoolss_PrinterInfo info1, info2;
3153 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3154 SEC_DESC *sd1, *sd2;
3158 printf("Retrieving printer security for %s...", cli1->desthost);
3159 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3164 if ( !W_ERROR_IS_OK(werror) ) {
3165 printf("failed (%s)\n", win_errstr(werror));
3171 printf("Retrieving printer security for %s...", cli2->desthost);
3172 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3177 if ( !W_ERROR_IS_OK(werror) ) {
3178 printf("failed (%s)\n", win_errstr(werror));
3187 sd1 = info1.info3.secdesc;
3188 sd2 = info2.info3.secdesc;
3190 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3191 printf("NULL secdesc!\n");
3196 if (!sec_desc_equal( sd1, sd2 ) ) {
3197 printf("Security Descriptors *not* equal!\n");
3202 printf("Security descriptors match\n");
3205 talloc_destroy(mem_ctx);
3210 /****************************************************************************
3211 ****************************************************************************/
3213 extern struct user_auth_info *rpcclient_auth_info;
3215 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3216 TALLOC_CTX *mem_ctx, int argc,
3219 const char *printername;
3220 char *printername_path = NULL;
3221 struct cli_state *cli_server2 = NULL;
3222 struct rpc_pipe_client *cli2 = NULL;
3223 struct policy_handle hPrinter1, hPrinter2;
3228 printf("Usage: %s <printer> <server>\n", argv[0]);
3232 printername = argv[1];
3234 /* first get the connection to the remote server */
3236 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3239 get_cmdline_auth_info_username(rpcclient_auth_info),
3241 get_cmdline_auth_info_password(rpcclient_auth_info),
3242 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3243 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3245 if ( !NT_STATUS_IS_OK(nt_status) )
3246 return WERR_GENERAL_FAILURE;
3248 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3250 if (!NT_STATUS_IS_OK(nt_status)) {
3251 printf("failed to open spoolss pipe on server %s (%s)\n",
3252 argv[2], nt_errstr(nt_status));
3253 return WERR_GENERAL_FAILURE;
3256 /* now open up both printers */
3258 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3260 printf("Opening %s...", printername_path);
3262 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3266 if ( !W_ERROR_IS_OK(werror) ) {
3267 printf("failed (%s)\n", win_errstr(werror));
3272 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3274 printf("Opening %s...", printername_path);
3275 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3279 if ( !W_ERROR_IS_OK(werror) ) {
3280 printf("failed (%s)\n", win_errstr(werror));
3285 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3286 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3288 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3295 printf("Closing printers...");
3296 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3297 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3300 /* close the second remote connection */
3302 cli_shutdown( cli_server2 );
3306 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3308 printf("print_processor_name: %s\n", r->print_processor_name);
3311 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3312 TALLOC_CTX *mem_ctx, int argc,
3316 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3317 uint32_t num_procs, level = 1, i;
3318 union spoolss_PrintProcessorInfo *procs;
3320 /* Parse the command arguments */
3322 if (argc < 1 || argc > 4) {
3323 printf ("Usage: %s [environment] [level]\n", argv[0]);
3328 environment = argv[1];
3332 level = atoi(argv[2]);
3335 /* Enumerate Print Processors */
3337 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3338 cli->srv_name_slash,
3344 if (!W_ERROR_IS_OK(werror))
3347 /* Display output */
3349 for (i = 0; i < num_procs; i++) {
3352 display_proc_info1(&procs[i].info1);
3361 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3363 printf("name_array: %s\n", r->name_array);
3366 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3367 TALLOC_CTX *mem_ctx, int argc,
3371 const char *print_processor_name = "winprint";
3372 uint32_t num_procs, level = 1, i;
3373 union spoolss_PrintProcDataTypesInfo *procs;
3375 /* Parse the command arguments */
3377 if (argc < 1 || argc > 4) {
3378 printf ("Usage: %s [environment] [level]\n", argv[0]);
3383 print_processor_name = argv[1];
3387 level = atoi(argv[2]);
3390 /* Enumerate Print Processor Data Types */
3392 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3393 cli->srv_name_slash,
3394 print_processor_name,
3399 if (!W_ERROR_IS_OK(werror))
3402 /* Display output */
3404 for (i = 0; i < num_procs; i++) {
3407 display_proc_data_types_info1(&procs[i].info1);
3416 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3418 printf("monitor_name: %s\n", r->monitor_name);
3421 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3423 printf("monitor_name: %s\n", r->monitor_name);
3424 printf("environment: %s\n", r->environment);
3425 printf("dll_name: %s\n", r->dll_name);
3428 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3429 TALLOC_CTX *mem_ctx, int argc,
3433 uint32_t count, level = 1, i;
3434 union spoolss_MonitorInfo *info;
3436 /* Parse the command arguments */
3439 printf("Usage: %s [level]\n", argv[0]);
3444 level = atoi(argv[1]);
3447 /* Enumerate Print Monitors */
3449 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3450 cli->srv_name_slash,
3455 if (!W_ERROR_IS_OK(werror)) {
3459 /* Display output */
3461 for (i = 0; i < count; i++) {
3464 display_monitor1(&info[i].info1);
3467 display_monitor2(&info[i].info2);
3476 /* List of commands exported by this module */
3477 struct cmd_set spoolss_commands[] = {
3481 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3482 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3483 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3484 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3485 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3486 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3487 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3488 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3489 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3490 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3491 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3492 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3493 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3494 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3495 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3496 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3497 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3498 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3499 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3500 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3501 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3502 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3503 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3504 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3505 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3506 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3507 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3508 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3509 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3510 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3511 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3512 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3513 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3514 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },