2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "rpcclient.h"
27 #include "../librpc/gen_ndr/cli_spoolss.h"
30 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
32 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
33 _cli->srv_name_slash, _arg); \
34 W_ERROR_HAVE_NO_MEMORY(_printername); \
37 /* The version int is used by getdrivers. Note that
38 all architecture strings that support mutliple
39 versions must be grouped together since enumdrivers
40 uses this property to prevent issuing multiple
41 enumdriver calls for the same arch */
44 static const struct print_architecture_table_node archi_table[]= {
46 {"Windows 4.0", "WIN40", 0 },
47 {"Windows NT x86", "W32X86", 2 },
48 {"Windows NT x86", "W32X86", 3 },
49 {"Windows NT R4000", "W32MIPS", 2 },
50 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
51 {"Windows NT PowerPC", "W32PPC", 2 },
52 {"Windows IA64", "IA64", 3 },
53 {"Windows x64", "x64", 3 },
60 * rpcclient module for SPOOLSS rpc pipe.
62 * This generally just parses and checks command lines, and then calls
63 * a cli_spoolss function.
66 /****************************************************************************
67 function to do the mapping between the long architecture name and
69 ****************************************************************************/
71 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
75 DEBUG(107,("Getting architecture dependant directory\n"));
78 } while ( (archi_table[i].long_archi!=NULL ) &&
79 StrCaseCmp(long_archi, archi_table[i].long_archi) );
81 if (archi_table[i].long_archi==NULL) {
82 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
86 /* this might be client code - but shouldn't this be an fstrcpy etc? */
89 DEBUGADD(108,("index: [%d]\n", i));
90 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
91 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
93 return archi_table[i].short_archi;
96 /****************************************************************************
97 ****************************************************************************/
99 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
101 int argc, const char **argv)
104 struct policy_handle hnd;
107 printf("Usage: %s <printername>\n", argv[0]);
112 return WERR_GENERAL_FAILURE;
114 /* Open the printer handle */
116 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
120 if (W_ERROR_IS_OK(werror)) {
121 printf("Printer %s opened successfully\n", argv[1]);
122 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
124 if (!W_ERROR_IS_OK(werror)) {
125 printf("Error closing printer handle! (%s)\n",
126 get_dos_error_msg(werror));
134 /****************************************************************************
135 ****************************************************************************/
137 static void display_print_info0(struct spoolss_PrinterInfo0 *r)
142 printf("\tprintername:[%s]\n", r->printername);
143 printf("\tservername:[%s]\n", r->servername);
144 printf("\tcjobs:[0x%x]\n", r->cjobs);
145 printf("\ttotal_jobs:[0x%x]\n", r->total_jobs);
146 printf("\ttotal_bytes:[0x%x]\n", r->total_bytes);
147 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month,
148 r->time.day, r->time.day_of_week);
149 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute,
150 r->time.second, r->time.millisecond);
152 printf("\tglobal_counter:[0x%x]\n", r->global_counter);
153 printf("\ttotal_pages:[0x%x]\n", r->total_pages);
155 printf("\tversion:[0x%x]\n", r->version);
156 printf("\tfree_build:[0x%x]\n", r->free_build);
157 printf("\tspooling:[0x%x]\n", r->spooling);
158 printf("\tmax_spooling:[0x%x]\n", r->max_spooling);
159 printf("\tsession_counter:[0x%x]\n", r->session_counter);
160 printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper);
161 printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready);
162 printf("\tjob_error:[0x%x]\n", r->job_error);
163 printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors);
164 printf("\tprocessor_type:[0x%x]\n", r->processor_type);
165 printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes);
166 printf("\tchange_id:[0x%x]\n", r->change_id);
167 printf("\tlast_error: %s\n", win_errstr(r->last_error));
168 printf("\tstatus:[0x%x]\n", r->status);
169 printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers);
170 printf("\tc_setprinter:[0x%x]\n", r->c_setprinter);
171 printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture);
172 printf("\tprocessor_level:[0x%x]\n", r->processor_level);
173 printf("\tref_ic:[0x%x]\n", r->ref_ic);
174 printf("\treserved2:[0x%x]\n", r->reserved2);
175 printf("\treserved3:[0x%x]\n", r->reserved3);
180 /****************************************************************************
181 ****************************************************************************/
183 static void display_print_info1(struct spoolss_PrinterInfo1 *r)
185 printf("\tflags:[0x%x]\n", r->flags);
186 printf("\tname:[%s]\n", r->name);
187 printf("\tdescription:[%s]\n", r->description);
188 printf("\tcomment:[%s]\n", r->comment);
193 /****************************************************************************
194 ****************************************************************************/
196 static void display_print_info2(struct spoolss_PrinterInfo2 *r)
198 printf("\tservername:[%s]\n", r->servername);
199 printf("\tprintername:[%s]\n", r->printername);
200 printf("\tsharename:[%s]\n", r->sharename);
201 printf("\tportname:[%s]\n", r->portname);
202 printf("\tdrivername:[%s]\n", r->drivername);
203 printf("\tcomment:[%s]\n", r->comment);
204 printf("\tlocation:[%s]\n", r->location);
205 printf("\tsepfile:[%s]\n", r->sepfile);
206 printf("\tprintprocessor:[%s]\n", r->printprocessor);
207 printf("\tdatatype:[%s]\n", r->datatype);
208 printf("\tparameters:[%s]\n", r->parameters);
209 printf("\tattributes:[0x%x]\n", r->attributes);
210 printf("\tpriority:[0x%x]\n", r->priority);
211 printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority);
212 printf("\tstarttime:[0x%x]\n", r->starttime);
213 printf("\tuntiltime:[0x%x]\n", r->untiltime);
214 printf("\tstatus:[0x%x]\n", r->status);
215 printf("\tcjobs:[0x%x]\n", r->cjobs);
216 printf("\taverageppm:[0x%x]\n", r->averageppm);
219 display_sec_desc(r->secdesc);
224 /****************************************************************************
225 ****************************************************************************/
227 static void display_print_info3(struct spoolss_PrinterInfo3 *r)
229 display_sec_desc(r->secdesc);
234 /****************************************************************************
235 ****************************************************************************/
237 static void display_print_info4(struct spoolss_PrinterInfo4 *r)
239 printf("\tservername:[%s]\n", r->servername);
240 printf("\tprintername:[%s]\n", r->printername);
241 printf("\tattributes:[0x%x]\n", r->attributes);
245 /****************************************************************************
246 ****************************************************************************/
248 static void display_print_info5(struct spoolss_PrinterInfo5 *r)
250 printf("\tprintername:[%s]\n", r->printername);
251 printf("\tportname:[%s]\n", r->portname);
252 printf("\tattributes:[0x%x]\n", r->attributes);
253 printf("\tdevice_not_selected_timeout:[0x%x]\n", r->device_not_selected_timeout);
254 printf("\ttransmission_retry_timeout:[0x%x]\n", r->transmission_retry_timeout);
258 /****************************************************************************
259 ****************************************************************************/
261 static void display_print_info6(struct spoolss_PrinterInfo6 *r)
263 printf("\tstatus:[0x%x]\n", r->status);
267 /****************************************************************************
268 ****************************************************************************/
270 static void display_print_info7(struct spoolss_PrinterInfo7 *r)
272 printf("\tguid:[%s]\n", r->guid);
273 printf("\taction:[0x%x]\n", r->action);
277 /****************************************************************************
278 ****************************************************************************/
280 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
282 int argc, const char **argv)
286 union spoolss_PrinterInfo *info;
289 uint32_t flags = PRINTER_ENUM_LOCAL;
292 printf("Usage: %s [level] [name] [flags]\n", argv[0]);
297 level = atoi(argv[1]);
303 name = cli->srv_name_slash;
307 flags = atoi(argv[3]);
310 result = rpccli_spoolss_enumprinters(cli, mem_ctx,
317 if (W_ERROR_IS_OK(result)) {
320 printf ("No printers returned.\n");
324 for (i = 0; i < count; i++) {
327 display_print_info0(&info[i].info0);
330 display_print_info1(&info[i].info1);
333 display_print_info2(&info[i].info2);
336 display_print_info3(&info[i].info3);
339 display_print_info4(&info[i].info4);
342 display_print_info5(&info[i].info5);
345 display_print_info6(&info[i].info6);
348 printf("unknown info level %d\n", level);
358 /****************************************************************************
359 ****************************************************************************/
361 static void display_port_info_1(struct spoolss_PortInfo1 *r)
363 printf("\tPort Name:\t[%s]\n", r->port_name);
366 /****************************************************************************
367 ****************************************************************************/
369 static void display_port_info_2(struct spoolss_PortInfo2 *r)
371 printf("\tPort Name:\t[%s]\n", r->port_name);
372 printf("\tMonitor Name:\t[%s]\n", r->monitor_name);
373 printf("\tDescription:\t[%s]\n", r->description);
374 printf("\tPort Type:\t" );
376 int comma = 0; /* hack */
378 if (r->port_type & SPOOLSS_PORT_TYPE_READ) {
382 if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) {
383 printf( "%sWrite", comma ? ", " : "" );
386 /* These two have slightly different interpretations
387 on 95/98/ME but I'm disregarding that for now */
388 if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) {
389 printf( "%sRedirected", comma ? ", " : "" );
392 if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) {
393 printf( "%sNet-Attached", comma ? ", " : "" );
397 printf( "[Unset]\n" );
399 printf("\tReserved:\t[%d]\n", r->reserved);
403 /****************************************************************************
404 ****************************************************************************/
406 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
407 TALLOC_CTX *mem_ctx, int argc,
413 union spoolss_PortInfo *info;
416 printf("Usage: %s [level]\n", argv[0]);
421 level = atoi(argv[1]);
424 /* Enumerate ports */
426 result = rpccli_spoolss_enumports(cli, mem_ctx,
432 if (W_ERROR_IS_OK(result)) {
435 for (i = 0; i < count; i++) {
438 display_port_info_1(&info[i].info1);
441 display_port_info_2(&info[i].info2);
444 printf("unknown info level %d\n", level);
453 /****************************************************************************
454 ****************************************************************************/
456 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
458 int argc, const char **argv)
460 struct policy_handle pol;
463 uint32_t info_level = 2;
464 union spoolss_PrinterInfo info;
465 struct spoolss_SetPrinterInfoCtr info_ctr;
466 struct spoolss_SetPrinterInfo2 info2;
467 const char *printername, *comment = NULL;
468 struct spoolss_DevmodeContainer devmode_ctr;
469 struct sec_desc_buf secdesc_ctr;
471 if (argc == 1 || argc > 3) {
472 printf("Usage: %s printername comment\n", argv[0]);
477 /* Open a printer handle */
482 ZERO_STRUCT(devmode_ctr);
483 ZERO_STRUCT(secdesc_ctr);
485 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
487 /* get a printer handle */
488 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
492 if (!W_ERROR_IS_OK(result))
495 /* Get printer info */
496 result = rpccli_spoolss_getprinter(cli, mem_ctx,
501 if (!W_ERROR_IS_OK(result))
505 /* Modify the comment. */
506 info2.servername = info.info2.servername;
507 info2.printername = info.info2.printername;
508 info2.sharename = info.info2.sharename;
509 info2.portname = info.info2.portname;
510 info2.drivername = info.info2.drivername;
511 info2.comment = comment;
512 info2.location = info.info2.location;
513 info2.devmode_ptr = 0;
514 info2.sepfile = info.info2.sepfile;
515 info2.printprocessor = info.info2.printprocessor;
516 info2.datatype = info.info2.datatype;
517 info2.parameters = info.info2.parameters;
518 info2.secdesc_ptr = 0;
519 info2.attributes = info.info2.attributes;
520 info2.priority = info.info2.priority;
521 info2.defaultpriority = info.info2.defaultpriority;
522 info2.starttime = info.info2.starttime;
523 info2.untiltime = info.info2.untiltime;
524 info2.status = info.info2.status;
525 info2.cjobs = info.info2.cjobs;
526 info2.averageppm = info.info2.averageppm;
529 info_ctr.info.info2 = &info2;
531 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
538 if (W_ERROR_IS_OK(result))
539 printf("Success in setting comment.\n");
542 if (is_valid_policy_hnd(&pol))
543 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
548 /****************************************************************************
549 ****************************************************************************/
551 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
553 int argc, const char **argv)
555 struct policy_handle pol;
558 uint32_t info_level = 2;
559 union spoolss_PrinterInfo info;
560 const char *printername,
561 *new_printername = NULL;
562 struct spoolss_SetPrinterInfoCtr info_ctr;
563 struct spoolss_SetPrinterInfo2 info2;
564 struct spoolss_DevmodeContainer devmode_ctr;
565 struct sec_desc_buf secdesc_ctr;
567 ZERO_STRUCT(devmode_ctr);
568 ZERO_STRUCT(secdesc_ctr);
570 if (argc == 1 || argc > 3) {
571 printf("Usage: %s printername new_printername\n", argv[0]);
576 /* Open a printer handle */
578 new_printername = argv[2];
581 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
583 /* get a printer handle */
584 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
588 if (!W_ERROR_IS_OK(result))
591 /* Get printer info */
592 result = rpccli_spoolss_getprinter(cli, mem_ctx,
597 if (!W_ERROR_IS_OK(result))
600 /* Modify the printername. */
601 info2.servername = info.info2.servername;
602 info2.printername = new_printername;
603 info2.sharename = info.info2.sharename;
604 info2.portname = info.info2.portname;
605 info2.drivername = info.info2.drivername;
606 info2.comment = info.info2.comment;
607 info2.location = info.info2.location;
608 info2.devmode_ptr = 0;
609 info2.sepfile = info.info2.sepfile;
610 info2.printprocessor = info.info2.printprocessor;
611 info2.datatype = info.info2.datatype;
612 info2.parameters = info.info2.parameters;
613 info2.secdesc_ptr = 0;
614 info2.attributes = info.info2.attributes;
615 info2.priority = info.info2.priority;
616 info2.defaultpriority = info.info2.defaultpriority;
617 info2.starttime = info.info2.starttime;
618 info2.untiltime = info.info2.untiltime;
619 info2.status = info.info2.status;
620 info2.cjobs = info.info2.cjobs;
621 info2.averageppm = info.info2.averageppm;
624 info_ctr.info.info2 = &info2;
626 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
633 if (W_ERROR_IS_OK(result))
634 printf("Success in setting printername.\n");
637 if (is_valid_policy_hnd(&pol))
638 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
643 /****************************************************************************
644 ****************************************************************************/
646 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
648 int argc, const char **argv)
650 struct policy_handle pol;
653 const char *printername;
654 union spoolss_PrinterInfo info;
656 if (argc == 1 || argc > 3) {
657 printf("Usage: %s <printername> [level]\n", argv[0]);
661 /* Open a printer handle */
663 level = atoi(argv[2]);
666 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
668 /* get a printer handle */
670 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
672 SEC_FLAG_MAXIMUM_ALLOWED,
674 if (!W_ERROR_IS_OK(result)) {
678 /* Get printer info */
680 result = rpccli_spoolss_getprinter(cli, mem_ctx,
685 if (!W_ERROR_IS_OK(result)) {
689 /* Display printer info */
692 display_print_info0(&info.info0);
695 display_print_info1(&info.info1);
698 display_print_info2(&info.info2);
701 display_print_info3(&info.info3);
704 display_print_info4(&info.info4);
707 display_print_info5(&info.info5);
710 display_print_info6(&info.info6);
713 display_print_info7(&info.info7);
716 printf("unknown info level %d\n", level);
720 if (is_valid_policy_hnd(&pol)) {
721 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
727 /****************************************************************************
728 ****************************************************************************/
730 static void display_reg_value(struct regval_blob value)
732 const char *text = NULL;
737 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
738 *((uint32_t *) value.data_p));
741 blob = data_blob_const(value.data_p, value.size);
742 pull_reg_sz(talloc_tos(), &blob, &text);
743 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
746 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
748 printf("%s: REG_BINARY:", value.valuename);
750 for (i=0; i<len; i++) {
751 if (hex[i] == '\0') {
766 blob = data_blob_const(value.data_p, value.size);
768 if (!pull_reg_multi_sz(NULL, &blob, &values)) {
769 d_printf("pull_reg_multi_sz failed\n");
773 printf("%s: REG_MULTI_SZ: \n", value.valuename);
774 for (i=0; values[i] != NULL; i++) {
775 d_printf("%s\n", values[i]);
781 printf("%s: unknown type %d\n", value.valuename, value.type);
786 /****************************************************************************
787 ****************************************************************************/
789 static void display_printer_data(const char *v,
790 enum winreg_Type type,
795 union spoolss_PrinterData r;
796 DATA_BLOB blob = data_blob_const(data, length);
799 result = pull_spoolss_PrinterData(talloc_tos(), &blob, &r, type);
800 if (!W_ERROR_IS_OK(result)) {
806 printf("%s: REG_DWORD: 0x%08x\n", v, r.value);
809 printf("%s: REG_SZ: %s\n", v, r.string);
812 char *hex = hex_encode_talloc(NULL,
813 r.binary.data, r.binary.length);
815 printf("%s: REG_BINARY:", v);
817 for (i=0; i<len; i++) {
818 if (hex[i] == '\0') {
831 printf("%s: REG_MULTI_SZ: ", v);
832 for (i=0; r.string_array[i] != NULL; i++) {
833 printf("%s ", r.string_array[i]);
838 printf("%s: unknown type 0x%02x:\n", v, type);
843 /****************************************************************************
844 ****************************************************************************/
846 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
848 int argc, const char **argv)
850 struct policy_handle pol;
853 const char *valuename;
854 enum winreg_Type type;
859 printf("Usage: %s <printername> <valuename>\n", argv[0]);
860 printf("<printername> of . queries print server\n");
865 /* Open a printer handle */
867 if (strncmp(argv[1], ".", sizeof(".")) == 0)
868 fstrcpy(printername, cli->srv_name_slash);
870 slprintf(printername, sizeof(printername)-1, "%s\\%s",
871 cli->srv_name_slash, argv[1]);
873 /* get a printer handle */
875 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
877 SEC_FLAG_MAXIMUM_ALLOWED,
879 if (!W_ERROR_IS_OK(result))
882 /* Get printer info */
884 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
891 if (!W_ERROR_IS_OK(result))
894 /* Display printer data */
896 display_printer_data(valuename, type, data, needed);
899 if (is_valid_policy_hnd(&pol))
900 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
905 /****************************************************************************
906 ****************************************************************************/
908 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
910 int argc, const char **argv)
912 struct policy_handle pol;
916 const char *valuename, *keyname;
918 enum winreg_Type type;
919 uint8_t *data = NULL;
920 uint32_t offered = 0;
924 printf("Usage: %s <printername> <keyname> <valuename>\n",
926 printf("<printername> of . queries print server\n");
932 /* Open a printer handle */
934 if (strncmp(argv[1], ".", sizeof(".")) == 0)
935 fstrcpy(printername, cli->srv_name_slash);
937 slprintf(printername, sizeof(printername)-1, "%s\\%s",
938 cli->srv_name_slash, argv[1]);
940 /* get a printer handle */
942 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
944 SEC_FLAG_MAXIMUM_ALLOWED,
946 if (!W_ERROR_IS_OK(result))
949 /* Get printer info */
951 data = talloc_zero_array(mem_ctx, uint8_t, offered);
956 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
965 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
967 data = talloc_zero_array(mem_ctx, uint8_t, offered);
971 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
982 if (!NT_STATUS_IS_OK(status)) {
986 if (!W_ERROR_IS_OK(result))
989 /* Display printer data */
991 display_printer_data(valuename, type, data, needed);
995 if (is_valid_policy_hnd(&pol))
996 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1001 /****************************************************************************
1002 ****************************************************************************/
1004 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
1010 printf("Printer Driver Info 1:\n");
1011 printf("\tDriver Name: [%s]\n", r->driver_name);
1015 /****************************************************************************
1016 ****************************************************************************/
1018 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
1024 printf("Printer Driver Info 2:\n");
1025 printf("\tVersion: [%x]\n", r->version);
1026 printf("\tDriver Name: [%s]\n", r->driver_name);
1027 printf("\tArchitecture: [%s]\n", r->architecture);
1028 printf("\tDriver Path: [%s]\n", r->driver_path);
1029 printf("\tDatafile: [%s]\n", r->data_file);
1030 printf("\tConfigfile: [%s]\n", r->config_file);
1034 /****************************************************************************
1035 ****************************************************************************/
1037 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1045 printf("Printer Driver Info 3:\n");
1046 printf("\tVersion: [%x]\n", r->version);
1047 printf("\tDriver Name: [%s]\n", r->driver_name);
1048 printf("\tArchitecture: [%s]\n", r->architecture);
1049 printf("\tDriver Path: [%s]\n", r->driver_path);
1050 printf("\tDatafile: [%s]\n", r->data_file);
1051 printf("\tConfigfile: [%s]\n", r->config_file);
1052 printf("\tHelpfile: [%s]\n", r->help_file);
1054 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1055 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1058 printf("\tMonitorname: [%s]\n", r->monitor_name);
1059 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1063 /****************************************************************************
1064 ****************************************************************************/
1066 static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1074 printf("Printer Driver Info 4:\n");
1075 printf("\tVersion: [%x]\n", r->version);
1076 printf("\tDriver Name: [%s]\n", r->driver_name);
1077 printf("\tArchitecture: [%s]\n", r->architecture);
1078 printf("\tDriver Path: [%s]\n", r->driver_path);
1079 printf("\tDatafile: [%s]\n", r->data_file);
1080 printf("\tConfigfile: [%s]\n", r->config_file);
1081 printf("\tHelpfile: [%s]\n", r->help_file);
1083 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1084 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1087 printf("\tMonitorname: [%s]\n", r->monitor_name);
1088 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1090 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1091 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1096 /****************************************************************************
1097 ****************************************************************************/
1099 static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1105 printf("Printer Driver Info 5:\n");
1106 printf("\tVersion: [%x]\n", r->version);
1107 printf("\tDriver Name: [%s]\n", r->driver_name);
1108 printf("\tArchitecture: [%s]\n", r->architecture);
1109 printf("\tDriver Path: [%s]\n", r->driver_path);
1110 printf("\tDatafile: [%s]\n", r->data_file);
1111 printf("\tConfigfile: [%s]\n", r->config_file);
1112 printf("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1113 printf("\tConfig Version: [0x%x]\n", r->config_version);
1114 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1118 /****************************************************************************
1119 ****************************************************************************/
1121 static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1129 printf("Printer Driver Info 6:\n");
1130 printf("\tVersion: [%x]\n", r->version);
1131 printf("\tDriver Name: [%s]\n", r->driver_name);
1132 printf("\tArchitecture: [%s]\n", r->architecture);
1133 printf("\tDriver Path: [%s]\n", r->driver_path);
1134 printf("\tDatafile: [%s]\n", r->data_file);
1135 printf("\tConfigfile: [%s]\n", r->config_file);
1136 printf("\tHelpfile: [%s]\n", r->help_file);
1138 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1139 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1142 printf("\tMonitorname: [%s]\n", r->monitor_name);
1143 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1145 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1146 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1149 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1150 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1151 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1152 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1153 printf("\tHardware ID: [%s]\n", r->hardware_id);
1154 printf("\tProvider: [%s]\n", r->provider);
1159 /****************************************************************************
1160 ****************************************************************************/
1162 static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1170 printf("Printer Driver Info 8:\n");
1171 printf("\tVersion: [%x]\n", r->version);
1172 printf("\tDriver Name: [%s]\n", r->driver_name);
1173 printf("\tArchitecture: [%s]\n", r->architecture);
1174 printf("\tDriver Path: [%s]\n", r->driver_path);
1175 printf("\tDatafile: [%s]\n", r->data_file);
1176 printf("\tConfigfile: [%s]\n", r->config_file);
1177 printf("\tHelpfile: [%s]\n", r->help_file);
1178 printf("\tMonitorname: [%s]\n", r->monitor_name);
1179 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1181 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1182 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1185 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1186 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1189 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1190 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1191 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1192 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1193 printf("\tHardware ID: [%s]\n", r->hardware_id);
1194 printf("\tProvider: [%s]\n", r->provider);
1195 printf("\tPrint Processor: [%s]\n", r->print_processor);
1196 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1197 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1198 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1200 printf("\tInf Path: [%s]\n", r->inf_path);
1201 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1202 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1203 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1205 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1206 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1207 (long long unsigned int)r->min_inbox_driver_ver_version);
1212 /****************************************************************************
1213 ****************************************************************************/
1215 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1216 TALLOC_CTX *mem_ctx,
1217 int argc, const char **argv)
1219 struct policy_handle pol;
1222 const char *printername;
1224 bool success = false;
1225 union spoolss_DriverInfo info;
1226 uint32_t server_major_version;
1227 uint32_t server_minor_version;
1229 if ((argc == 1) || (argc > 3)) {
1230 printf("Usage: %s <printername> [level]\n", argv[0]);
1234 /* get the arguments need to open the printer handle */
1236 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1239 level = atoi(argv[2]);
1242 /* Open a printer handle */
1244 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1248 if (!W_ERROR_IS_OK(werror)) {
1249 printf("Error opening printer handle for %s!\n", printername);
1253 /* loop through and print driver info level for each architecture */
1255 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1257 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1259 archi_table[i].long_archi,
1262 archi_table[i].version,
1265 &server_major_version,
1266 &server_minor_version);
1267 if (!W_ERROR_IS_OK(werror)) {
1271 /* need at least one success */
1275 printf("\n[%s]\n", archi_table[i].long_archi);
1279 display_print_driver1(&info.info1);
1282 display_print_driver2(&info.info2);
1285 display_print_driver3(&info.info3);
1288 display_print_driver4(&info.info4);
1291 display_print_driver5(&info.info5);
1294 display_print_driver6(&info.info6);
1297 display_print_driver8(&info.info8);
1300 printf("unknown info level %d\n", level);
1307 if (is_valid_policy_hnd(&pol)) {
1308 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1318 /****************************************************************************
1319 ****************************************************************************/
1321 static WERROR enum_driver_by_architecture(struct rpc_pipe_client *cli,
1322 TALLOC_CTX *mem_ctx,
1323 const char *architecture,
1328 union spoolss_DriverInfo *info = NULL;
1331 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1332 cli->srv_name_slash,
1339 if (W_ERROR_EQUAL(werror, WERR_INVALID_ENVIRONMENT)) {
1340 printf("Server does not support environment [%s]\n",
1349 if (!W_ERROR_IS_OK(werror)) {
1350 printf("Error getting driver for environment [%s] - %s\n",
1351 architecture, win_errstr(werror));
1355 printf("\n[%s]\n", architecture);
1359 for (j=0; j < count; j++) {
1360 display_print_driver1(&info[j].info1);
1364 for (j=0; j < count; j++) {
1365 display_print_driver2(&info[j].info2);
1369 for (j=0; j < count; j++) {
1370 display_print_driver3(&info[j].info3);
1374 for (j=0; j < count; j++) {
1375 display_print_driver4(&info[j].info4);
1379 for (j=0; j < count; j++) {
1380 display_print_driver5(&info[j].info5);
1384 for (j=0; j < count; j++) {
1385 display_print_driver6(&info[j].info6);
1389 for (j=0; j < count; j++) {
1390 display_print_driver8(&info[j].info8);
1394 printf("unknown info level %d\n", level);
1395 return WERR_UNKNOWN_LEVEL;
1401 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1402 TALLOC_CTX *mem_ctx,
1403 int argc, const char **argv)
1405 WERROR werror = WERR_OK;
1408 const char *architecture = NULL;
1411 printf("Usage: enumdrivers [level] [architecture]\n");
1416 level = atoi(argv[1]);
1420 architecture = argv[2];
1424 return enum_driver_by_architecture(cli, mem_ctx,
1429 /* loop through and print driver info level for each architecture */
1430 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1431 /* check to see if we already asked for this architecture string */
1433 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1437 werror = enum_driver_by_architecture(cli, mem_ctx,
1438 archi_table[i].long_archi,
1440 if (!W_ERROR_IS_OK(werror)) {
1448 /****************************************************************************
1449 ****************************************************************************/
1451 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1453 printf("\tDirectory Name:[%s]\n", r->directory_name);
1456 /****************************************************************************
1457 ****************************************************************************/
1459 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1460 TALLOC_CTX *mem_ctx,
1461 int argc, const char **argv)
1465 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1468 union spoolss_DriverDirectoryInfo info;
1472 printf("Usage: %s [environment]\n", argv[0]);
1476 /* Get the arguments need to open the printer handle */
1482 /* Get the directory. Only use Info level 1 */
1484 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1485 cli->srv_name_slash,
1493 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1495 buffer = data_blob_talloc_zero(mem_ctx, needed);
1497 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1498 cli->srv_name_slash,
1508 if (W_ERROR_IS_OK(result)) {
1509 display_printdriverdir_1(&info.info1);
1515 /****************************************************************************
1516 ****************************************************************************/
1518 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1519 struct spoolss_AddDriverInfo3 *info,
1525 for (i=0; archi_table[i].long_archi != NULL; i++)
1527 if (strcmp(arch, archi_table[i].short_archi) == 0)
1529 info->version = archi_table[i].version;
1530 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1535 if (archi_table[i].long_archi == NULL)
1537 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1544 /**************************************************************************
1545 wrapper for strtok to get the next parameter from a delimited list.
1546 Needed to handle the empty parameter string denoted by "NULL"
1547 *************************************************************************/
1549 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1550 const char *delim, const char **dest,
1555 /* get the next token */
1556 ptr = strtok_r(str, delim, saveptr);
1558 /* a string of 'NULL' is used to represent an empty
1559 parameter because two consecutive delimiters
1560 will not return an empty string. See man strtok(3)
1562 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1567 *dest = talloc_strdup(mem_ctx, ptr);
1573 /********************************************************************************
1574 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1575 string in the form of
1576 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1577 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1578 <Default Data Type>:<Comma Separated list of Files>
1579 *******************************************************************************/
1581 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1586 char *saveptr = NULL;
1587 struct spoolss_StringArray *deps;
1588 const char **file_array = NULL;
1591 /* fill in the UNISTR fields */
1592 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1593 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1594 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1595 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1596 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1597 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1598 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1600 /* <Comma Separated List of Dependent Files> */
1601 /* save the beginning of the string */
1602 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1605 /* begin to strip out each filename */
1606 str = strtok_r(str, ",", &saveptr);
1608 /* no dependent files, we are done */
1613 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1618 while (str != NULL) {
1619 add_string_to_array(deps, str, &file_array, &count);
1620 str = strtok_r(NULL, ",", &saveptr);
1623 deps->string = talloc_zero_array(deps, const char *, count + 1);
1624 if (!deps->string) {
1628 for (i=0; i < count; i++) {
1629 deps->string[i] = file_array[i];
1632 r->dependent_files = deps;
1637 /****************************************************************************
1638 ****************************************************************************/
1640 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1641 TALLOC_CTX *mem_ctx,
1642 int argc, const char **argv)
1647 struct spoolss_AddDriverInfoCtr info_ctr;
1648 struct spoolss_AddDriverInfo3 info3;
1652 /* parse the command arguments */
1653 if (argc != 3 && argc != 4)
1655 printf ("Usage: %s <Environment> \\\n", argv[0]);
1656 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1657 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1658 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1659 printf ("\t[version]\n");
1664 /* Fill in the spoolss_AddDriverInfo3 struct */
1667 arch = cmd_spoolss_get_short_archi(argv[1]);
1669 printf ("Error Unknown architechture [%s]\n", argv[1]);
1670 return WERR_INVALID_PARAM;
1673 set_drv_info_3_env(mem_ctx, &info3, arch);
1675 driver_args = talloc_strdup( mem_ctx, argv[2] );
1676 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1678 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1679 return WERR_INVALID_PARAM;
1682 /* if printer driver version specified, override the default version
1683 * used by the architecture. This allows installation of Windows
1684 * 2000 (version 3) printer drivers. */
1687 info3.version = atoi(argv[3]);
1691 info_ctr.level = level;
1692 info_ctr.info.info3 = &info3;
1694 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1695 cli->srv_name_slash,
1698 if (!NT_STATUS_IS_OK(status)) {
1699 return ntstatus_to_werror(status);
1701 if (W_ERROR_IS_OK(result)) {
1702 printf ("Printer Driver %s successfully installed.\n",
1710 /****************************************************************************
1711 ****************************************************************************/
1713 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1714 TALLOC_CTX *mem_ctx,
1715 int argc, const char **argv)
1718 struct spoolss_SetPrinterInfoCtr info_ctr;
1719 struct spoolss_SetPrinterInfo2 info2;
1721 /* parse the command arguments */
1724 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1728 /* Fill in the DRIVER_INFO_2 struct */
1731 info2.printername = argv[1];
1732 info2.drivername = argv[3];
1733 info2.sharename = argv[2];
1734 info2.portname = argv[4];
1735 info2.comment = "Created by rpcclient";
1736 info2.printprocessor = "winprint";
1737 info2.datatype = "RAW";
1738 info2.devmode_ptr = 0;
1739 info2.secdesc_ptr = 0;
1740 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1742 info2.defaultpriority = 0;
1743 info2.starttime = 0;
1744 info2.untiltime = 0;
1746 /* These three fields must not be used by AddPrinter()
1747 as defined in the MS Platform SDK documentation..
1751 info2.averageppm = 0;
1755 info_ctr.info.info2 = &info2;
1757 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1759 if (W_ERROR_IS_OK(result))
1760 printf ("Printer %s successfully installed.\n", argv[1]);
1765 /****************************************************************************
1766 ****************************************************************************/
1768 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1769 TALLOC_CTX *mem_ctx,
1770 int argc, const char **argv)
1772 struct policy_handle pol;
1776 const char *printername;
1777 union spoolss_PrinterInfo info;
1778 struct spoolss_SetPrinterInfoCtr info_ctr;
1779 struct spoolss_SetPrinterInfo2 info2;
1780 struct spoolss_DevmodeContainer devmode_ctr;
1781 struct sec_desc_buf secdesc_ctr;
1783 ZERO_STRUCT(devmode_ctr);
1784 ZERO_STRUCT(secdesc_ctr);
1786 /* parse the command arguments */
1789 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1793 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1795 /* Get a printer handle */
1797 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1801 if (!W_ERROR_IS_OK(result))
1804 /* Get printer info */
1806 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1811 if (!W_ERROR_IS_OK(result)) {
1812 printf ("Unable to retrieve printer information!\n");
1816 /* Set the printer driver */
1818 info2.servername = info.info2.servername;
1819 info2.printername = info.info2.printername;
1820 info2.sharename = info.info2.sharename;
1821 info2.portname = info.info2.portname;
1822 info2.drivername = argv[2];
1823 info2.comment = info.info2.comment;
1824 info2.location = info.info2.location;
1825 info2.devmode_ptr = 0;
1826 info2.sepfile = info.info2.sepfile;
1827 info2.printprocessor = info.info2.printprocessor;
1828 info2.datatype = info.info2.datatype;
1829 info2.parameters = info.info2.parameters;
1830 info2.secdesc_ptr = 0;
1831 info2.attributes = info.info2.attributes;
1832 info2.priority = info.info2.priority;
1833 info2.defaultpriority = info.info2.defaultpriority;
1834 info2.starttime = info.info2.starttime;
1835 info2.untiltime = info.info2.untiltime;
1836 info2.status = info.info2.status;
1837 info2.cjobs = info.info2.cjobs;
1838 info2.averageppm = info.info2.averageppm;
1841 info_ctr.info.info2 = &info2;
1843 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1850 if (!W_ERROR_IS_OK(result)) {
1851 printf("SetPrinter call failed!\n");
1855 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1860 if (is_valid_policy_hnd(&pol))
1861 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1867 /****************************************************************************
1868 ****************************************************************************/
1870 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1871 TALLOC_CTX *mem_ctx,
1872 int argc, const char **argv)
1874 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1880 const char *arch = NULL;
1881 uint32_t delete_flags = 0;
1883 /* parse the command arguments */
1884 if (argc < 2 || argc > 4) {
1885 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1892 vers = atoi (argv[3]);
1895 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1898 /* delete the driver for all architectures */
1899 for (i=0; archi_table[i].long_archi; i++) {
1901 if (arch && !strequal( archi_table[i].long_archi, arch))
1904 if (vers >= 0 && archi_table[i].version != vers)
1907 /* make the call to remove the driver */
1908 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1909 cli->srv_name_slash,
1910 archi_table[i].long_archi,
1913 archi_table[i].version,
1916 if ( !W_ERROR_IS_OK(result) )
1918 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1919 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1920 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1925 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1926 archi_table[i].long_archi, archi_table[i].version);
1935 /****************************************************************************
1936 ****************************************************************************/
1938 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1939 TALLOC_CTX *mem_ctx,
1940 int argc, const char **argv)
1942 WERROR result = WERR_OK;
1946 /* parse the command arguments */
1948 printf ("Usage: %s <driver>\n", argv[0]);
1952 /* delete the driver for all architectures */
1953 for (i=0; archi_table[i].long_archi; i++) {
1954 /* make the call to remove the driver */
1955 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1956 cli->srv_name_slash,
1957 archi_table[i].long_archi,
1960 if (!NT_STATUS_IS_OK(status)) {
1963 if ( !W_ERROR_IS_OK(result) ) {
1964 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1965 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1966 argv[1], archi_table[i].long_archi,
1970 printf ("Driver %s removed for arch [%s].\n", argv[1],
1971 archi_table[i].long_archi);
1978 /****************************************************************************
1979 ****************************************************************************/
1981 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1982 TALLOC_CTX *mem_ctx,
1983 int argc, const char **argv)
1987 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1990 union spoolss_PrintProcessorDirectoryInfo info;
1993 /* parse the command arguments */
1995 printf ("Usage: %s [environment]\n", argv[0]);
2000 environment = argv[1];
2003 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
2004 cli->srv_name_slash,
2012 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
2014 buffer = data_blob_talloc_zero(mem_ctx, needed);
2016 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
2017 cli->srv_name_slash,
2027 if (W_ERROR_IS_OK(result)) {
2028 printf("%s\n", info.info1.directory_name);
2034 /****************************************************************************
2035 ****************************************************************************/
2037 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2038 int argc, const char **argv)
2040 struct policy_handle handle;
2043 const char *printername;
2044 union spoolss_AddFormInfo info;
2045 struct spoolss_AddFormInfo1 info1;
2046 struct spoolss_AddFormInfo2 info2;
2049 /* Parse the command arguments */
2051 if (argc < 3 || argc > 5) {
2052 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2056 /* Get a printer handle */
2058 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2060 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2064 if (!W_ERROR_IS_OK(werror))
2067 /* Dummy up some values for the form data */
2070 level = atoi(argv[3]);
2075 info1.flags = SPOOLSS_FORM_USER;
2076 info1.form_name = argv[2];
2077 info1.size.width = 100;
2078 info1.size.height = 100;
2079 info1.area.left = 0;
2080 info1.area.top = 10;
2081 info1.area.right = 20;
2082 info1.area.bottom = 30;
2084 info.info1 = &info1;
2088 info2.flags = SPOOLSS_FORM_USER;
2089 info2.form_name = argv[2];
2090 info2.size.width = 100;
2091 info2.size.height = 100;
2092 info2.area.left = 0;
2093 info2.area.top = 10;
2094 info2.area.right = 20;
2095 info2.area.bottom = 30;
2096 info2.keyword = argv[2];
2097 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2098 info2.mui_dll = NULL;
2099 info2.ressource_id = 0;
2100 info2.display_name = argv[2];
2103 info.info2 = &info2;
2111 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2118 if (is_valid_policy_hnd(&handle))
2119 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2124 /****************************************************************************
2125 ****************************************************************************/
2127 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2128 int argc, const char **argv)
2130 struct policy_handle handle;
2133 const char *printername;
2134 union spoolss_AddFormInfo info;
2135 struct spoolss_AddFormInfo1 info1;
2137 /* Parse the command arguments */
2140 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2144 /* Get a printer handle */
2146 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2148 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2150 SEC_FLAG_MAXIMUM_ALLOWED,
2152 if (!W_ERROR_IS_OK(werror))
2155 /* Dummy up some values for the form data */
2157 info1.flags = SPOOLSS_FORM_PRINTER;
2158 info1.size.width = 100;
2159 info1.size.height = 100;
2160 info1.area.left = 0;
2161 info1.area.top = 1000;
2162 info1.area.right = 2000;
2163 info1.area.bottom = 3000;
2164 info1.form_name = argv[2];
2166 info.info1 = &info1;
2170 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2178 if (is_valid_policy_hnd(&handle))
2179 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2184 /****************************************************************************
2185 ****************************************************************************/
2187 static const char *get_form_flag(int form_flag)
2189 switch (form_flag) {
2190 case SPOOLSS_FORM_USER:
2192 case SPOOLSS_FORM_BUILTIN:
2193 return "FORM_BUILTIN";
2194 case SPOOLSS_FORM_PRINTER:
2195 return "FORM_PRINTER";
2201 /****************************************************************************
2202 ****************************************************************************/
2204 static void display_form_info1(struct spoolss_FormInfo1 *r)
2207 "\tflag: %s (%d)\n" \
2208 "\twidth: %d, length: %d\n" \
2209 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2210 r->form_name, get_form_flag(r->flags), r->flags,
2211 r->size.width, r->size.height,
2212 r->area.left, r->area.right,
2213 r->area.top, r->area.bottom);
2216 /****************************************************************************
2217 ****************************************************************************/
2219 static void display_form_info2(struct spoolss_FormInfo2 *r)
2222 "\tflag: %s (%d)\n" \
2223 "\twidth: %d, length: %d\n" \
2224 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2225 r->form_name, get_form_flag(r->flags), r->flags,
2226 r->size.width, r->size.height,
2227 r->area.left, r->area.right,
2228 r->area.top, r->area.bottom);
2229 printf("\tkeyword: %s\n", r->keyword);
2230 printf("\tstring_type: 0x%08x\n", r->string_type);
2231 printf("\tmui_dll: %s\n", r->mui_dll);
2232 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2233 printf("\tdisplay_name: %s\n", r->display_name);
2234 printf("\tlang_id: %d\n", r->lang_id);
2238 /****************************************************************************
2239 ****************************************************************************/
2241 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2242 int argc, const char **argv)
2244 struct policy_handle handle;
2247 const char *printername;
2249 uint32_t offered = 0;
2250 union spoolss_FormInfo info;
2254 /* Parse the command arguments */
2256 if (argc < 3 || argc > 5) {
2257 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2261 /* Get a printer handle */
2263 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2265 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2267 SEC_FLAG_MAXIMUM_ALLOWED,
2269 if (!W_ERROR_IS_OK(werror))
2273 level = atoi(argv[3]);
2278 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2287 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2288 buffer = data_blob_talloc_zero(mem_ctx, needed);
2290 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2301 if (!NT_STATUS_IS_OK(status)) {
2307 display_form_info1(&info.info1);
2310 display_form_info2(&info.info2);
2315 if (is_valid_policy_hnd(&handle))
2316 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2321 /****************************************************************************
2322 ****************************************************************************/
2324 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2325 TALLOC_CTX *mem_ctx, int argc,
2328 struct policy_handle handle;
2331 const char *printername;
2333 /* Parse the command arguments */
2336 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2340 /* Get a printer handle */
2342 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2344 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2346 SEC_FLAG_MAXIMUM_ALLOWED,
2348 if (!W_ERROR_IS_OK(werror))
2351 /* Delete the form */
2353 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2357 if (!NT_STATUS_IS_OK(status)) {
2358 return ntstatus_to_werror(status);
2362 if (is_valid_policy_hnd(&handle))
2363 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2368 /****************************************************************************
2369 ****************************************************************************/
2371 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2372 TALLOC_CTX *mem_ctx, int argc,
2375 struct policy_handle handle;
2377 const char *printername;
2378 uint32_t num_forms, level = 1, i;
2379 union spoolss_FormInfo *forms;
2381 /* Parse the command arguments */
2383 if (argc < 2 || argc > 4) {
2384 printf ("Usage: %s <printer> [level]\n", argv[0]);
2388 /* Get a printer handle */
2390 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2392 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2394 SEC_FLAG_MAXIMUM_ALLOWED,
2396 if (!W_ERROR_IS_OK(werror))
2400 level = atoi(argv[2]);
2403 /* Enumerate forms */
2405 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2412 if (!W_ERROR_IS_OK(werror))
2415 /* Display output */
2417 for (i = 0; i < num_forms; i++) {
2420 display_form_info1(&forms[i].info1);
2423 display_form_info2(&forms[i].info2);
2429 if (is_valid_policy_hnd(&handle))
2430 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2435 /****************************************************************************
2436 ****************************************************************************/
2438 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2439 TALLOC_CTX *mem_ctx,
2440 int argc, const char **argv)
2444 const char *printername;
2445 struct policy_handle pol;
2446 union spoolss_PrinterInfo info;
2447 enum winreg_Type type;
2448 union spoolss_PrinterData data;
2451 /* parse the command arguments */
2453 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2454 " <value> <data>\n",
2459 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2463 if (strequal(argv[2], "string")) {
2467 if (strequal(argv[2], "binary")) {
2471 if (strequal(argv[2], "dword")) {
2475 if (strequal(argv[2], "multistring")) {
2476 type = REG_MULTI_SZ;
2479 if (type == REG_NONE) {
2480 printf("Unknown data type: %s\n", argv[2]);
2481 result = WERR_INVALID_PARAM;
2485 /* get a printer handle */
2487 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2489 SEC_FLAG_MAXIMUM_ALLOWED,
2491 if (!W_ERROR_IS_OK(result)) {
2495 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2500 if (!W_ERROR_IS_OK(result)) {
2504 printf("%s\n", current_timestring(mem_ctx, true));
2505 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2507 /* Set the printer data */
2511 data.string = talloc_strdup(mem_ctx, argv[4]);
2512 W_ERROR_HAVE_NO_MEMORY(data.string);
2515 data.value = strtoul(argv[4], NULL, 10);
2518 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2520 case REG_MULTI_SZ: {
2522 const char **strings = NULL;
2524 for (i=4; i<argc; i++) {
2525 if (strcmp(argv[i], "NULL") == 0) {
2528 if (!add_string_to_array(mem_ctx, argv[i],
2531 result = WERR_NOMEM;
2535 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2536 if (!data.string_array) {
2537 result = WERR_NOMEM;
2540 for (i=0; i < num_strings; i++) {
2541 data.string_array[i] = strings[i];
2546 printf("Unknown data type: %s\n", argv[2]);
2547 result = WERR_INVALID_PARAM;
2551 result = push_spoolss_PrinterData(mem_ctx, &blob, type, &data);
2552 if (!W_ERROR_IS_OK(result)) {
2556 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2558 argv[3], /* value_name */
2563 if (!W_ERROR_IS_OK(result)) {
2564 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2567 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2569 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2574 if (!W_ERROR_IS_OK(result)) {
2578 printf("%s\n", current_timestring(mem_ctx, true));
2579 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2583 if (is_valid_policy_hnd(&pol)) {
2584 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2590 /****************************************************************************
2591 ****************************************************************************/
2593 static void display_job_info1(struct spoolss_JobInfo1 *r)
2595 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2596 r->user_name, r->document_name, r->text_status, r->pages_printed,
2600 /****************************************************************************
2601 ****************************************************************************/
2603 static void display_job_info2(struct spoolss_JobInfo2 *r)
2605 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2606 r->position, r->job_id,
2607 r->user_name, r->document_name, r->text_status, r->pages_printed,
2608 r->total_pages, r->size);
2611 /****************************************************************************
2612 ****************************************************************************/
2614 static void display_job_info3(struct spoolss_JobInfo3 *r)
2616 printf("jobid[%d], next_jobid[%d]\n",
2617 r->job_id, r->next_job_id);
2620 /****************************************************************************
2621 ****************************************************************************/
2623 static void display_job_info4(struct spoolss_JobInfo4 *r)
2625 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2626 r->position, r->job_id,
2627 r->user_name, r->document_name, r->text_status, r->pages_printed,
2628 r->total_pages, r->size, r->size_high);
2631 /****************************************************************************
2632 ****************************************************************************/
2634 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2635 TALLOC_CTX *mem_ctx, int argc,
2639 uint32_t level = 1, count, i;
2640 const char *printername;
2641 struct policy_handle hnd;
2642 union spoolss_JobInfo *info;
2644 if (argc < 2 || argc > 3) {
2645 printf("Usage: %s printername [level]\n", argv[0]);
2650 level = atoi(argv[2]);
2653 /* Open printer handle */
2655 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2657 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2659 SEC_FLAG_MAXIMUM_ALLOWED,
2661 if (!W_ERROR_IS_OK(result))
2664 /* Enumerate ports */
2666 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2674 if (!W_ERROR_IS_OK(result)) {
2678 for (i = 0; i < count; i++) {
2681 display_job_info1(&info[i].info1);
2684 display_job_info2(&info[i].info2);
2687 d_printf("unknown info level %d\n", level);
2693 if (is_valid_policy_hnd(&hnd)) {
2694 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2700 /****************************************************************************
2701 ****************************************************************************/
2703 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2704 TALLOC_CTX *mem_ctx, int argc,
2708 const char *printername;
2709 struct policy_handle hnd;
2712 union spoolss_JobInfo info;
2714 if (argc < 3 || argc > 4) {
2715 printf("Usage: %s printername job_id [level]\n", argv[0]);
2719 job_id = atoi(argv[2]);
2722 level = atoi(argv[3]);
2725 /* Open printer handle */
2727 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2729 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2731 SEC_FLAG_MAXIMUM_ALLOWED,
2733 if (!W_ERROR_IS_OK(result)) {
2737 /* Enumerate ports */
2739 result = rpccli_spoolss_getjob(cli, mem_ctx,
2746 if (!W_ERROR_IS_OK(result)) {
2752 display_job_info1(&info.info1);
2755 display_job_info2(&info.info2);
2758 display_job_info3(&info.info3);
2761 display_job_info4(&info.info4);
2764 d_printf("unknown info level %d\n", level);
2769 if (is_valid_policy_hnd(&hnd)) {
2770 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2776 /****************************************************************************
2777 ****************************************************************************/
2779 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2780 TALLOC_CTX *mem_ctx, int argc,
2785 const char *printername;
2786 struct policy_handle hnd;
2788 enum spoolss_JobControl command;
2791 printf("Usage: %s printername job_id command\n", argv[0]);
2795 job_id = atoi(argv[2]);
2796 command = atoi(argv[3]);
2798 /* Open printer handle */
2800 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2802 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2804 SEC_FLAG_MAXIMUM_ALLOWED,
2806 if (!W_ERROR_IS_OK(result)) {
2812 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2819 if (!W_ERROR_IS_OK(result)) {
2824 if (is_valid_policy_hnd(&hnd)) {
2825 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2831 /****************************************************************************
2832 ****************************************************************************/
2834 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2835 TALLOC_CTX *mem_ctx, int argc,
2841 const char *printername;
2842 struct policy_handle hnd;
2843 uint32_t value_offered = 0;
2844 const char *value_name = NULL;
2845 uint32_t value_needed;
2846 enum winreg_Type type;
2847 uint8_t *data = NULL;
2848 uint32_t data_offered = 0;
2849 uint32_t data_needed;
2852 printf("Usage: %s printername\n", argv[0]);
2856 /* Open printer handle */
2858 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2860 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2862 SEC_FLAG_MAXIMUM_ALLOWED,
2864 if (!W_ERROR_IS_OK(result)) {
2868 /* Enumerate data */
2870 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2882 data_offered = data_needed;
2883 value_offered = value_needed;
2884 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2885 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2887 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2889 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2900 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2901 struct regval_blob v;
2902 fstrcpy(v.valuename, value_name);
2904 v.size = data_offered;
2906 display_reg_value(v);
2910 if (W_ERROR_V(result) == ERRnomoreitems) {
2911 result = W_ERROR(ERRsuccess);
2915 if (is_valid_policy_hnd(&hnd)) {
2916 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2922 /****************************************************************************
2923 ****************************************************************************/
2925 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2926 TALLOC_CTX *mem_ctx, int argc,
2931 const char *printername;
2932 struct policy_handle hnd;
2934 struct spoolss_PrinterEnumValues *info;
2937 printf("Usage: %s printername <keyname>\n", argv[0]);
2941 /* Open printer handle */
2943 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2945 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2947 SEC_FLAG_MAXIMUM_ALLOWED,
2949 if (!W_ERROR_IS_OK(result)) {
2953 /* Enumerate subkeys */
2955 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
2961 if (!W_ERROR_IS_OK(result)) {
2965 for (i=0; i < count; i++) {
2966 display_printer_data(info[i].value_name,
2969 info[i].data->length);
2973 if (is_valid_policy_hnd(&hnd)) {
2974 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2980 /****************************************************************************
2981 ****************************************************************************/
2983 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
2984 TALLOC_CTX *mem_ctx, int argc,
2988 const char *printername;
2989 const char *keyname = NULL;
2990 struct policy_handle hnd;
2991 const char **key_buffer = NULL;
2993 uint32_t offered = 0;
2995 if (argc < 2 || argc > 4) {
2996 printf("Usage: %s printername [keyname] [offered]\n", argv[0]);
3007 offered = atoi(argv[3]);
3010 /* Open printer handle */
3012 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3014 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3016 SEC_FLAG_MAXIMUM_ALLOWED,
3018 if (!W_ERROR_IS_OK(result)) {
3022 /* Enumerate subkeys */
3024 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
3030 if (!W_ERROR_IS_OK(result)) {
3034 for (i=0; key_buffer && key_buffer[i]; i++) {
3035 printf("%s\n", key_buffer[i]);
3040 if (is_valid_policy_hnd(&hnd)) {
3041 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3047 /****************************************************************************
3048 ****************************************************************************/
3050 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
3051 TALLOC_CTX *mem_ctx, int argc,
3054 const char *printername;
3055 const char *clientname;
3056 struct policy_handle hnd;
3059 struct spoolss_NotifyOption option;
3062 printf("Usage: %s printername\n", argv[0]);
3069 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3071 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3073 SEC_FLAG_MAXIMUM_ALLOWED,
3075 if (!W_ERROR_IS_OK(result)) {
3076 printf("Error opening %s\n", argv[1]);
3080 /* Create spool options */
3085 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3086 if (option.types == NULL) {
3087 result = WERR_NOMEM;
3091 option.types[0].type = PRINTER_NOTIFY_TYPE;
3092 option.types[0].count = 1;
3093 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3094 if (option.types[0].fields == NULL) {
3095 result = WERR_NOMEM;
3098 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3100 option.types[1].type = JOB_NOTIFY_TYPE;
3101 option.types[1].count = 1;
3102 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3103 if (option.types[1].fields == NULL) {
3104 result = WERR_NOMEM;
3107 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3109 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3111 result = WERR_NOMEM;
3117 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3125 if (!W_ERROR_IS_OK(result)) {
3126 printf("Error rffpcnex %s\n", argv[1]);
3131 if (is_valid_policy_hnd(&hnd))
3132 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3137 /****************************************************************************
3138 ****************************************************************************/
3140 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3141 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3143 union spoolss_PrinterInfo info1, info2;
3145 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3147 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3148 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3153 if ( !W_ERROR_IS_OK(werror) ) {
3154 printf("failed (%s)\n", win_errstr(werror));
3155 talloc_destroy(mem_ctx);
3160 printf("Retrieving printer properties for %s...", cli2->desthost);
3161 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3166 if ( !W_ERROR_IS_OK(werror) ) {
3167 printf("failed (%s)\n", win_errstr(werror));
3168 talloc_destroy(mem_ctx);
3173 talloc_destroy(mem_ctx);
3178 /****************************************************************************
3179 ****************************************************************************/
3181 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3182 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3184 union spoolss_PrinterInfo info1, info2;
3186 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3187 struct security_descriptor *sd1, *sd2;
3191 printf("Retrieving printer security for %s...", cli1->desthost);
3192 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3197 if ( !W_ERROR_IS_OK(werror) ) {
3198 printf("failed (%s)\n", win_errstr(werror));
3204 printf("Retrieving printer security for %s...", cli2->desthost);
3205 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3210 if ( !W_ERROR_IS_OK(werror) ) {
3211 printf("failed (%s)\n", win_errstr(werror));
3220 sd1 = info1.info3.secdesc;
3221 sd2 = info2.info3.secdesc;
3223 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3224 printf("NULL secdesc!\n");
3229 if (!security_descriptor_equal( sd1, sd2 ) ) {
3230 printf("Security Descriptors *not* equal!\n");
3235 printf("Security descriptors match\n");
3238 talloc_destroy(mem_ctx);
3243 /****************************************************************************
3244 ****************************************************************************/
3246 extern struct user_auth_info *rpcclient_auth_info;
3248 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3249 TALLOC_CTX *mem_ctx, int argc,
3252 const char *printername;
3253 char *printername_path = NULL;
3254 struct cli_state *cli_server2 = NULL;
3255 struct rpc_pipe_client *cli2 = NULL;
3256 struct policy_handle hPrinter1, hPrinter2;
3261 printf("Usage: %s <printer> <server>\n", argv[0]);
3265 printername = argv[1];
3267 /* first get the connection to the remote server */
3269 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3272 get_cmdline_auth_info_username(rpcclient_auth_info),
3274 get_cmdline_auth_info_password(rpcclient_auth_info),
3275 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3276 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3278 if ( !NT_STATUS_IS_OK(nt_status) )
3279 return WERR_GENERAL_FAILURE;
3281 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3283 if (!NT_STATUS_IS_OK(nt_status)) {
3284 printf("failed to open spoolss pipe on server %s (%s)\n",
3285 argv[2], nt_errstr(nt_status));
3286 return WERR_GENERAL_FAILURE;
3289 /* now open up both printers */
3291 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3293 printf("Opening %s...", printername_path);
3295 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3299 if ( !W_ERROR_IS_OK(werror) ) {
3300 printf("failed (%s)\n", win_errstr(werror));
3305 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3307 printf("Opening %s...", printername_path);
3308 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3312 if ( !W_ERROR_IS_OK(werror) ) {
3313 printf("failed (%s)\n", win_errstr(werror));
3318 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3319 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3321 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3328 printf("Closing printers...");
3329 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3330 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3333 /* close the second remote connection */
3335 cli_shutdown( cli_server2 );
3339 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3341 printf("print_processor_name: %s\n", r->print_processor_name);
3344 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3345 TALLOC_CTX *mem_ctx, int argc,
3349 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3350 uint32_t num_procs, level = 1, i;
3351 union spoolss_PrintProcessorInfo *procs;
3353 /* Parse the command arguments */
3355 if (argc < 1 || argc > 4) {
3356 printf ("Usage: %s [environment] [level]\n", argv[0]);
3361 environment = argv[1];
3365 level = atoi(argv[2]);
3368 /* Enumerate Print Processors */
3370 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3371 cli->srv_name_slash,
3377 if (!W_ERROR_IS_OK(werror))
3380 /* Display output */
3382 for (i = 0; i < num_procs; i++) {
3385 display_proc_info1(&procs[i].info1);
3394 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3396 printf("name_array: %s\n", r->name_array);
3399 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3400 TALLOC_CTX *mem_ctx, int argc,
3404 const char *print_processor_name = "winprint";
3405 uint32_t num_procs, level = 1, i;
3406 union spoolss_PrintProcDataTypesInfo *procs;
3408 /* Parse the command arguments */
3410 if (argc < 1 || argc > 4) {
3411 printf ("Usage: %s [environment] [level]\n", argv[0]);
3416 print_processor_name = argv[1];
3420 level = atoi(argv[2]);
3423 /* Enumerate Print Processor Data Types */
3425 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3426 cli->srv_name_slash,
3427 print_processor_name,
3432 if (!W_ERROR_IS_OK(werror))
3435 /* Display output */
3437 for (i = 0; i < num_procs; i++) {
3440 display_proc_data_types_info1(&procs[i].info1);
3449 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3451 printf("monitor_name: %s\n", r->monitor_name);
3454 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3456 printf("monitor_name: %s\n", r->monitor_name);
3457 printf("environment: %s\n", r->environment);
3458 printf("dll_name: %s\n", r->dll_name);
3461 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3462 TALLOC_CTX *mem_ctx, int argc,
3466 uint32_t count, level = 1, i;
3467 union spoolss_MonitorInfo *info;
3469 /* Parse the command arguments */
3472 printf("Usage: %s [level]\n", argv[0]);
3477 level = atoi(argv[1]);
3480 /* Enumerate Print Monitors */
3482 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3483 cli->srv_name_slash,
3488 if (!W_ERROR_IS_OK(werror)) {
3492 /* Display output */
3494 for (i = 0; i < count; i++) {
3497 display_monitor1(&info[i].info1);
3500 display_monitor2(&info[i].info2);
3509 static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
3510 TALLOC_CTX *mem_ctx, int argc,
3515 struct policy_handle handle, gdi_handle;
3516 const char *printername;
3517 struct spoolss_DevmodeContainer devmode_ctr;
3519 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3521 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3523 SEC_FLAG_MAXIMUM_ALLOWED,
3525 if (!W_ERROR_IS_OK(result)) {
3529 ZERO_STRUCT(devmode_ctr);
3531 status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx,
3536 if (!W_ERROR_IS_OK(result)) {
3541 if (is_valid_policy_hnd(&gdi_handle)) {
3542 rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL);
3544 if (is_valid_policy_hnd(&handle)) {
3545 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
3551 /* List of commands exported by this module */
3552 struct cmd_set spoolss_commands[] = {
3556 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3557 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3558 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3559 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3560 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3561 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3562 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3563 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3564 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3565 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3566 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3567 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3568 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3569 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3570 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3571 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3572 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3573 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3574 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3575 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3576 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3577 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3578 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3579 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3580 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3581 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3582 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3583 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3584 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3585 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3586 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3587 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3588 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3589 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
3590 { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" },