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); \
36 const char *long_archi;
37 const char *short_archi;
41 /* The version int is used by getdrivers. Note that
42 all architecture strings that support mutliple
43 versions must be grouped together since enumdrivers
44 uses this property to prevent issuing multiple
45 enumdriver calls for the same arch */
48 static const struct table_node archi_table[]= {
50 {"Windows 4.0", "WIN40", 0 },
51 {"Windows NT x86", "W32X86", 2 },
52 {"Windows NT x86", "W32X86", 3 },
53 {"Windows NT R4000", "W32MIPS", 2 },
54 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
55 {"Windows NT PowerPC", "W32PPC", 2 },
56 {"Windows IA64", "IA64", 3 },
57 {"Windows x64", "x64", 3 },
64 * rpcclient module for SPOOLSS rpc pipe.
66 * This generally just parses and checks command lines, and then calls
67 * a cli_spoolss function.
70 /****************************************************************************
71 function to do the mapping between the long architecture name and
73 ****************************************************************************/
75 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
79 DEBUG(107,("Getting architecture dependant directory\n"));
82 } while ( (archi_table[i].long_archi!=NULL ) &&
83 StrCaseCmp(long_archi, archi_table[i].long_archi) );
85 if (archi_table[i].long_archi==NULL) {
86 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
90 /* this might be client code - but shouldn't this be an fstrcpy etc? */
93 DEBUGADD(108,("index: [%d]\n", i));
94 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
95 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
97 return archi_table[i].short_archi;
100 /****************************************************************************
101 ****************************************************************************/
103 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
105 int argc, const char **argv)
108 struct policy_handle hnd;
111 printf("Usage: %s <printername>\n", argv[0]);
116 return WERR_GENERAL_FAILURE;
118 /* Open the printer handle */
120 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
124 if (W_ERROR_IS_OK(werror)) {
125 printf("Printer %s opened successfully\n", argv[1]);
126 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
128 if (!W_ERROR_IS_OK(werror)) {
129 printf("Error closing printer handle! (%s)\n",
130 get_dos_error_msg(werror));
138 /****************************************************************************
139 ****************************************************************************/
141 static void display_print_info0(struct spoolss_PrinterInfo0 *r)
146 printf("\tprintername:[%s]\n", r->printername);
147 printf("\tservername:[%s]\n", r->servername);
148 printf("\tcjobs:[0x%x]\n", r->cjobs);
149 printf("\ttotal_jobs:[0x%x]\n", r->total_jobs);
150 printf("\ttotal_bytes:[0x%x]\n", r->total_bytes);
151 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month,
152 r->time.day, r->time.day_of_week);
153 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute,
154 r->time.second, r->time.millisecond);
156 printf("\tglobal_counter:[0x%x]\n", r->global_counter);
157 printf("\ttotal_pages:[0x%x]\n", r->total_pages);
159 printf("\tversion:[0x%x]\n", r->version);
160 printf("\tfree_build:[0x%x]\n", r->free_build);
161 printf("\tspooling:[0x%x]\n", r->spooling);
162 printf("\tmax_spooling:[0x%x]\n", r->max_spooling);
163 printf("\tsession_counter:[0x%x]\n", r->session_counter);
164 printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper);
165 printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready);
166 printf("\tjob_error:[0x%x]\n", r->job_error);
167 printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors);
168 printf("\tprocessor_type:[0x%x]\n", r->processor_type);
169 printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes);
170 printf("\tchange_id:[0x%x]\n", r->change_id);
171 printf("\tlast_error: %s\n", win_errstr(r->last_error));
172 printf("\tstatus:[0x%x]\n", r->status);
173 printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers);
174 printf("\tc_setprinter:[0x%x]\n", r->c_setprinter);
175 printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture);
176 printf("\tprocessor_level:[0x%x]\n", r->processor_level);
177 printf("\tref_ic:[0x%x]\n", r->ref_ic);
178 printf("\treserved2:[0x%x]\n", r->reserved2);
179 printf("\treserved3:[0x%x]\n", r->reserved3);
184 /****************************************************************************
185 ****************************************************************************/
187 static void display_print_info1(struct spoolss_PrinterInfo1 *r)
189 printf("\tflags:[0x%x]\n", r->flags);
190 printf("\tname:[%s]\n", r->name);
191 printf("\tdescription:[%s]\n", r->description);
192 printf("\tcomment:[%s]\n", r->comment);
197 /****************************************************************************
198 ****************************************************************************/
200 static void display_print_info2(struct spoolss_PrinterInfo2 *r)
202 printf("\tservername:[%s]\n", r->servername);
203 printf("\tprintername:[%s]\n", r->printername);
204 printf("\tsharename:[%s]\n", r->sharename);
205 printf("\tportname:[%s]\n", r->portname);
206 printf("\tdrivername:[%s]\n", r->drivername);
207 printf("\tcomment:[%s]\n", r->comment);
208 printf("\tlocation:[%s]\n", r->location);
209 printf("\tsepfile:[%s]\n", r->sepfile);
210 printf("\tprintprocessor:[%s]\n", r->printprocessor);
211 printf("\tdatatype:[%s]\n", r->datatype);
212 printf("\tparameters:[%s]\n", r->parameters);
213 printf("\tattributes:[0x%x]\n", r->attributes);
214 printf("\tpriority:[0x%x]\n", r->priority);
215 printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority);
216 printf("\tstarttime:[0x%x]\n", r->starttime);
217 printf("\tuntiltime:[0x%x]\n", r->untiltime);
218 printf("\tstatus:[0x%x]\n", r->status);
219 printf("\tcjobs:[0x%x]\n", r->cjobs);
220 printf("\taverageppm:[0x%x]\n", r->averageppm);
223 display_sec_desc(r->secdesc);
228 /****************************************************************************
229 ****************************************************************************/
231 static void display_print_info3(struct spoolss_PrinterInfo3 *r)
233 display_sec_desc(r->secdesc);
238 /****************************************************************************
239 ****************************************************************************/
241 static void display_print_info4(struct spoolss_PrinterInfo4 *r)
243 printf("\tservername:[%s]\n", r->servername);
244 printf("\tprintername:[%s]\n", r->printername);
245 printf("\tattributes:[0x%x]\n", r->attributes);
249 /****************************************************************************
250 ****************************************************************************/
252 static void display_print_info5(struct spoolss_PrinterInfo5 *r)
254 printf("\tprintername:[%s]\n", r->printername);
255 printf("\tportname:[%s]\n", r->portname);
256 printf("\tattributes:[0x%x]\n", r->attributes);
257 printf("\tdevice_not_selected_timeout:[0x%x]\n", r->device_not_selected_timeout);
258 printf("\ttransmission_retry_timeout:[0x%x]\n", r->transmission_retry_timeout);
262 /****************************************************************************
263 ****************************************************************************/
265 static void display_print_info6(struct spoolss_PrinterInfo6 *r)
267 printf("\tstatus:[0x%x]\n", r->status);
271 /****************************************************************************
272 ****************************************************************************/
274 static void display_print_info7(struct spoolss_PrinterInfo7 *r)
276 printf("\tguid:[%s]\n", r->guid);
277 printf("\taction:[0x%x]\n", r->action);
281 /****************************************************************************
282 ****************************************************************************/
284 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
286 int argc, const char **argv)
290 union spoolss_PrinterInfo *info;
293 uint32_t flags = PRINTER_ENUM_LOCAL;
296 printf("Usage: %s [level] [name] [flags]\n", argv[0]);
301 level = atoi(argv[1]);
307 name = cli->srv_name_slash;
311 flags = atoi(argv[3]);
314 result = rpccli_spoolss_enumprinters(cli, mem_ctx,
321 if (W_ERROR_IS_OK(result)) {
324 printf ("No printers returned.\n");
328 for (i = 0; i < count; i++) {
331 display_print_info0(&info[i].info0);
334 display_print_info1(&info[i].info1);
337 display_print_info2(&info[i].info2);
340 display_print_info3(&info[i].info3);
343 display_print_info4(&info[i].info4);
346 display_print_info5(&info[i].info5);
349 display_print_info6(&info[i].info6);
352 printf("unknown info level %d\n", level);
362 /****************************************************************************
363 ****************************************************************************/
365 static void display_port_info_1(struct spoolss_PortInfo1 *r)
367 printf("\tPort Name:\t[%s]\n", r->port_name);
370 /****************************************************************************
371 ****************************************************************************/
373 static void display_port_info_2(struct spoolss_PortInfo2 *r)
375 printf("\tPort Name:\t[%s]\n", r->port_name);
376 printf("\tMonitor Name:\t[%s]\n", r->monitor_name);
377 printf("\tDescription:\t[%s]\n", r->description);
378 printf("\tPort Type:\t" );
380 int comma = 0; /* hack */
382 if (r->port_type & SPOOLSS_PORT_TYPE_READ) {
386 if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) {
387 printf( "%sWrite", comma ? ", " : "" );
390 /* These two have slightly different interpretations
391 on 95/98/ME but I'm disregarding that for now */
392 if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) {
393 printf( "%sRedirected", comma ? ", " : "" );
396 if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) {
397 printf( "%sNet-Attached", comma ? ", " : "" );
401 printf( "[Unset]\n" );
403 printf("\tReserved:\t[%d]\n", r->reserved);
407 /****************************************************************************
408 ****************************************************************************/
410 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
411 TALLOC_CTX *mem_ctx, int argc,
417 union spoolss_PortInfo *info;
420 printf("Usage: %s [level]\n", argv[0]);
425 level = atoi(argv[1]);
428 /* Enumerate ports */
430 result = rpccli_spoolss_enumports(cli, mem_ctx,
436 if (W_ERROR_IS_OK(result)) {
439 for (i = 0; i < count; i++) {
442 display_port_info_1(&info[i].info1);
445 display_port_info_2(&info[i].info2);
448 printf("unknown info level %d\n", level);
457 /****************************************************************************
458 ****************************************************************************/
460 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
462 int argc, const char **argv)
464 struct policy_handle pol;
467 uint32_t info_level = 2;
468 union spoolss_PrinterInfo info;
469 struct spoolss_SetPrinterInfoCtr info_ctr;
470 const char *printername, *comment = NULL;
471 struct spoolss_DevmodeContainer devmode_ctr;
472 struct sec_desc_buf secdesc_ctr;
474 if (argc == 1 || argc > 3) {
475 printf("Usage: %s printername comment\n", argv[0]);
480 /* Open a printer handle */
485 ZERO_STRUCT(devmode_ctr);
486 ZERO_STRUCT(secdesc_ctr);
488 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
490 /* get a printer handle */
491 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
495 if (!W_ERROR_IS_OK(result))
498 /* Get printer info */
499 result = rpccli_spoolss_getprinter(cli, mem_ctx,
504 if (!W_ERROR_IS_OK(result))
508 /* Modify the comment. */
509 info.info2.comment = comment;
510 info.info2.secdesc = NULL;
511 info.info2.devmode = NULL;
514 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
516 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
523 if (W_ERROR_IS_OK(result))
524 printf("Success in setting comment.\n");
527 if (is_valid_policy_hnd(&pol))
528 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
533 /****************************************************************************
534 ****************************************************************************/
536 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
538 int argc, const char **argv)
540 struct policy_handle pol;
543 uint32_t info_level = 2;
544 union spoolss_PrinterInfo info;
545 const char *printername,
546 *new_printername = NULL;
547 struct spoolss_SetPrinterInfoCtr info_ctr;
548 struct spoolss_DevmodeContainer devmode_ctr;
549 struct sec_desc_buf secdesc_ctr;
551 ZERO_STRUCT(devmode_ctr);
552 ZERO_STRUCT(secdesc_ctr);
554 if (argc == 1 || argc > 3) {
555 printf("Usage: %s printername new_printername\n", argv[0]);
560 /* Open a printer handle */
562 new_printername = argv[2];
565 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
567 /* get a printer handle */
568 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
572 if (!W_ERROR_IS_OK(result))
575 /* Get printer info */
576 result = rpccli_spoolss_getprinter(cli, mem_ctx,
581 if (!W_ERROR_IS_OK(result))
584 /* Modify the printername. */
585 info.info2.printername = new_printername;
586 info.info2.devmode = NULL;
587 info.info2.secdesc = NULL;
589 info_ctr.level = info_level;
590 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
592 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
599 if (W_ERROR_IS_OK(result))
600 printf("Success in setting printername.\n");
603 if (is_valid_policy_hnd(&pol))
604 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
609 /****************************************************************************
610 ****************************************************************************/
612 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
614 int argc, const char **argv)
616 struct policy_handle pol;
619 const char *printername;
620 union spoolss_PrinterInfo info;
622 if (argc == 1 || argc > 3) {
623 printf("Usage: %s <printername> [level]\n", argv[0]);
627 /* Open a printer handle */
629 level = atoi(argv[2]);
632 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
634 /* get a printer handle */
636 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
638 SEC_FLAG_MAXIMUM_ALLOWED,
640 if (!W_ERROR_IS_OK(result)) {
644 /* Get printer info */
646 result = rpccli_spoolss_getprinter(cli, mem_ctx,
651 if (!W_ERROR_IS_OK(result)) {
655 /* Display printer info */
658 display_print_info0(&info.info0);
661 display_print_info1(&info.info1);
664 display_print_info2(&info.info2);
667 display_print_info3(&info.info3);
670 display_print_info4(&info.info4);
673 display_print_info5(&info.info5);
676 display_print_info6(&info.info6);
679 display_print_info7(&info.info7);
682 printf("unknown info level %d\n", level);
686 if (is_valid_policy_hnd(&pol)) {
687 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
693 /****************************************************************************
694 ****************************************************************************/
696 static void display_reg_value(struct regval_blob value)
702 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
703 *((uint32_t *) value.data_p));
706 rpcstr_pull_talloc(talloc_tos(),
711 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
714 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
716 printf("%s: REG_BINARY:", value.valuename);
718 for (i=0; i<len; i++) {
719 if (hex[i] == '\0') {
732 uint32_t i, num_values;
735 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
736 value.size, &num_values,
738 d_printf("reg_pull_multi_sz failed\n");
742 printf("%s: REG_MULTI_SZ: \n", value.valuename);
743 for (i=0; i<num_values; i++) {
744 d_printf("%s\n", values[i]);
750 printf("%s: unknown type %d\n", value.valuename, value.type);
755 /****************************************************************************
756 ****************************************************************************/
758 static void display_printer_data(const char *v,
759 enum winreg_Type type,
760 union spoolss_PrinterData *r)
766 printf("%s: REG_DWORD: 0x%08x\n", v, r->value);
769 printf("%s: REG_SZ: %s\n", v, r->string);
772 char *hex = hex_encode_talloc(NULL,
773 r->binary.data, r->binary.length);
775 printf("%s: REG_BINARY:", v);
777 for (i=0; i<len; i++) {
778 if (hex[i] == '\0') {
791 printf("%s: REG_MULTI_SZ: ", v);
792 for (i=0; r->string_array[i] != NULL; i++) {
793 printf("%s ", r->string_array[i]);
798 printf("%s: unknown type 0x%02x:\n", v, type);
803 /****************************************************************************
804 ****************************************************************************/
806 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
808 int argc, const char **argv)
810 struct policy_handle pol;
813 const char *valuename;
814 enum winreg_Type type;
815 union spoolss_PrinterData data;
818 printf("Usage: %s <printername> <valuename>\n", argv[0]);
819 printf("<printername> of . queries print server\n");
824 /* Open a printer handle */
826 if (strncmp(argv[1], ".", sizeof(".")) == 0)
827 fstrcpy(printername, cli->srv_name_slash);
829 slprintf(printername, sizeof(printername)-1, "%s\\%s",
830 cli->srv_name_slash, argv[1]);
832 /* get a printer handle */
834 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
836 SEC_FLAG_MAXIMUM_ALLOWED,
838 if (!W_ERROR_IS_OK(result))
841 /* Get printer info */
843 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
849 if (!W_ERROR_IS_OK(result))
852 /* Display printer data */
854 display_printer_data(valuename, type, &data);
857 if (is_valid_policy_hnd(&pol))
858 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
863 /****************************************************************************
864 ****************************************************************************/
866 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
868 int argc, const char **argv)
870 struct policy_handle pol;
874 const char *valuename, *keyname;
875 struct regval_blob value;
877 enum winreg_Type type;
878 uint8_t *buffer = NULL;
879 uint32_t offered = 0;
883 printf("Usage: %s <printername> <keyname> <valuename>\n",
885 printf("<printername> of . queries print server\n");
891 /* Open a printer handle */
893 if (strncmp(argv[1], ".", sizeof(".")) == 0)
894 fstrcpy(printername, cli->srv_name_slash);
896 slprintf(printername, sizeof(printername)-1, "%s\\%s",
897 cli->srv_name_slash, argv[1]);
899 /* get a printer handle */
901 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
903 SEC_FLAG_MAXIMUM_ALLOWED,
905 if (!W_ERROR_IS_OK(result))
908 /* Get printer info */
910 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
919 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
921 buffer = talloc_array(mem_ctx, uint8_t, needed);
922 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
933 if (!NT_STATUS_IS_OK(status)) {
937 if (!W_ERROR_IS_OK(result)) {
942 if (!W_ERROR_IS_OK(result))
945 /* Display printer data */
947 fstrcpy(value.valuename, valuename);
950 value.data_p = buffer;
952 display_reg_value(value);
955 if (is_valid_policy_hnd(&pol))
956 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
961 /****************************************************************************
962 ****************************************************************************/
964 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
970 printf("Printer Driver Info 1:\n");
971 printf("\tDriver Name: [%s]\n", r->driver_name);
975 /****************************************************************************
976 ****************************************************************************/
978 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
984 printf("Printer Driver Info 2:\n");
985 printf("\tVersion: [%x]\n", r->version);
986 printf("\tDriver Name: [%s]\n", r->driver_name);
987 printf("\tArchitecture: [%s]\n", r->architecture);
988 printf("\tDriver Path: [%s]\n", r->driver_path);
989 printf("\tDatafile: [%s]\n", r->data_file);
990 printf("\tConfigfile: [%s]\n", r->config_file);
994 /****************************************************************************
995 ****************************************************************************/
997 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1005 printf("Printer Driver Info 3:\n");
1006 printf("\tVersion: [%x]\n", r->version);
1007 printf("\tDriver Name: [%s]\n", r->driver_name);
1008 printf("\tArchitecture: [%s]\n", r->architecture);
1009 printf("\tDriver Path: [%s]\n", r->driver_path);
1010 printf("\tDatafile: [%s]\n", r->data_file);
1011 printf("\tConfigfile: [%s]\n", r->config_file);
1012 printf("\tHelpfile: [%s]\n", r->help_file);
1014 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1015 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1018 printf("\tMonitorname: [%s]\n", r->monitor_name);
1019 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1023 /****************************************************************************
1024 ****************************************************************************/
1026 static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1034 printf("Printer Driver Info 4:\n");
1035 printf("\tVersion: [%x]\n", r->version);
1036 printf("\tDriver Name: [%s]\n", r->driver_name);
1037 printf("\tArchitecture: [%s]\n", r->architecture);
1038 printf("\tDriver Path: [%s]\n", r->driver_path);
1039 printf("\tDatafile: [%s]\n", r->data_file);
1040 printf("\tConfigfile: [%s]\n", r->config_file);
1041 printf("\tHelpfile: [%s]\n", r->help_file);
1043 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1044 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1047 printf("\tMonitorname: [%s]\n", r->monitor_name);
1048 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1050 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1051 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1056 /****************************************************************************
1057 ****************************************************************************/
1059 static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1065 printf("Printer Driver Info 5:\n");
1066 printf("\tVersion: [%x]\n", r->version);
1067 printf("\tDriver Name: [%s]\n", r->driver_name);
1068 printf("\tArchitecture: [%s]\n", r->architecture);
1069 printf("\tDriver Path: [%s]\n", r->driver_path);
1070 printf("\tDatafile: [%s]\n", r->data_file);
1071 printf("\tConfigfile: [%s]\n", r->config_file);
1072 printf("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1073 printf("\tConfig Version: [0x%x]\n", r->config_version);
1074 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1078 /****************************************************************************
1079 ****************************************************************************/
1081 static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1089 printf("Printer Driver Info 6:\n");
1090 printf("\tVersion: [%x]\n", r->version);
1091 printf("\tDriver Name: [%s]\n", r->driver_name);
1092 printf("\tArchitecture: [%s]\n", r->architecture);
1093 printf("\tDriver Path: [%s]\n", r->driver_path);
1094 printf("\tDatafile: [%s]\n", r->data_file);
1095 printf("\tConfigfile: [%s]\n", r->config_file);
1096 printf("\tHelpfile: [%s]\n", r->help_file);
1098 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1099 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1102 printf("\tMonitorname: [%s]\n", r->monitor_name);
1103 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1105 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1106 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1109 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1110 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1111 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1112 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1113 printf("\tHardware ID: [%s]\n", r->hardware_id);
1114 printf("\tProvider: [%s]\n", r->provider);
1119 /****************************************************************************
1120 ****************************************************************************/
1122 static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1130 printf("Printer Driver Info 8:\n");
1131 printf("\tVersion: [%x]\n", r->version);
1132 printf("\tDriver Name: [%s]\n", r->driver_name);
1133 printf("\tArchitecture: [%s]\n", r->architecture);
1134 printf("\tDriver Path: [%s]\n", r->driver_path);
1135 printf("\tDatafile: [%s]\n", r->data_file);
1136 printf("\tConfigfile: [%s]\n", r->config_file);
1137 printf("\tHelpfile: [%s]\n", r->help_file);
1138 printf("\tMonitorname: [%s]\n", r->monitor_name);
1139 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1141 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1142 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
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);
1155 printf("\tPrint Processor: [%s]\n", r->print_processor);
1156 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1157 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1158 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1160 printf("\tInf Path: [%s]\n", r->inf_path);
1161 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1162 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1163 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1165 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1166 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1167 (long long unsigned int)r->min_inbox_driver_ver_version);
1172 /****************************************************************************
1173 ****************************************************************************/
1175 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1176 TALLOC_CTX *mem_ctx,
1177 int argc, const char **argv)
1179 struct policy_handle pol;
1182 const char *printername;
1184 bool success = false;
1185 union spoolss_DriverInfo info;
1186 uint32_t server_major_version;
1187 uint32_t server_minor_version;
1189 if ((argc == 1) || (argc > 3)) {
1190 printf("Usage: %s <printername> [level]\n", argv[0]);
1194 /* get the arguments need to open the printer handle */
1196 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1199 level = atoi(argv[2]);
1202 /* Open a printer handle */
1204 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1208 if (!W_ERROR_IS_OK(werror)) {
1209 printf("Error opening printer handle for %s!\n", printername);
1213 /* loop through and print driver info level for each architecture */
1215 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1217 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1219 archi_table[i].long_archi,
1222 archi_table[i].version,
1225 &server_major_version,
1226 &server_minor_version);
1227 if (!W_ERROR_IS_OK(werror)) {
1231 /* need at least one success */
1235 printf("\n[%s]\n", archi_table[i].long_archi);
1239 display_print_driver1(&info.info1);
1242 display_print_driver2(&info.info2);
1245 display_print_driver3(&info.info3);
1248 display_print_driver4(&info.info4);
1251 display_print_driver5(&info.info5);
1254 display_print_driver6(&info.info6);
1257 display_print_driver8(&info.info8);
1260 printf("unknown info level %d\n", level);
1267 if (is_valid_policy_hnd(&pol)) {
1268 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1278 /****************************************************************************
1279 ****************************************************************************/
1281 static WERROR enum_driver_by_architecture(struct rpc_pipe_client *cli,
1282 TALLOC_CTX *mem_ctx,
1283 const char *architecture,
1288 union spoolss_DriverInfo *info = NULL;
1291 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1292 cli->srv_name_slash,
1299 if (W_ERROR_EQUAL(werror, WERR_INVALID_ENVIRONMENT)) {
1300 printf("Server does not support environment [%s]\n",
1309 if (!W_ERROR_IS_OK(werror)) {
1310 printf("Error getting driver for environment [%s] - %s\n",
1311 architecture, win_errstr(werror));
1315 printf("\n[%s]\n", architecture);
1319 for (j=0; j < count; j++) {
1320 display_print_driver1(&info[j].info1);
1324 for (j=0; j < count; j++) {
1325 display_print_driver2(&info[j].info2);
1329 for (j=0; j < count; j++) {
1330 display_print_driver3(&info[j].info3);
1334 for (j=0; j < count; j++) {
1335 display_print_driver4(&info[j].info4);
1339 for (j=0; j < count; j++) {
1340 display_print_driver5(&info[j].info5);
1344 for (j=0; j < count; j++) {
1345 display_print_driver6(&info[j].info6);
1349 for (j=0; j < count; j++) {
1350 display_print_driver8(&info[j].info8);
1354 printf("unknown info level %d\n", level);
1355 return WERR_UNKNOWN_LEVEL;
1361 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1362 TALLOC_CTX *mem_ctx,
1363 int argc, const char **argv)
1365 WERROR werror = WERR_OK;
1368 const char *architecture = NULL;
1371 printf("Usage: enumdrivers [level] [architecture]\n");
1376 level = atoi(argv[1]);
1380 architecture = argv[2];
1384 return enum_driver_by_architecture(cli, mem_ctx,
1389 /* loop through and print driver info level for each architecture */
1390 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1391 /* check to see if we already asked for this architecture string */
1393 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1397 werror = enum_driver_by_architecture(cli, mem_ctx,
1398 archi_table[i].long_archi,
1400 if (!W_ERROR_IS_OK(werror)) {
1408 /****************************************************************************
1409 ****************************************************************************/
1411 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1413 printf("\tDirectory Name:[%s]\n", r->directory_name);
1416 /****************************************************************************
1417 ****************************************************************************/
1419 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1420 TALLOC_CTX *mem_ctx,
1421 int argc, const char **argv)
1425 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1428 union spoolss_DriverDirectoryInfo info;
1432 printf("Usage: %s [environment]\n", argv[0]);
1436 /* Get the arguments need to open the printer handle */
1442 /* Get the directory. Only use Info level 1 */
1444 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1445 cli->srv_name_slash,
1453 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1455 buffer = data_blob_talloc_zero(mem_ctx, needed);
1457 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1458 cli->srv_name_slash,
1468 if (W_ERROR_IS_OK(result)) {
1469 display_printdriverdir_1(&info.info1);
1475 /****************************************************************************
1476 ****************************************************************************/
1478 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1479 struct spoolss_AddDriverInfo3 *info,
1485 for (i=0; archi_table[i].long_archi != NULL; i++)
1487 if (strcmp(arch, archi_table[i].short_archi) == 0)
1489 info->version = archi_table[i].version;
1490 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1495 if (archi_table[i].long_archi == NULL)
1497 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1504 /**************************************************************************
1505 wrapper for strtok to get the next parameter from a delimited list.
1506 Needed to handle the empty parameter string denoted by "NULL"
1507 *************************************************************************/
1509 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1510 const char *delim, const char **dest,
1515 /* get the next token */
1516 ptr = strtok_r(str, delim, saveptr);
1518 /* a string of 'NULL' is used to represent an empty
1519 parameter because two consecutive delimiters
1520 will not return an empty string. See man strtok(3)
1522 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1527 *dest = talloc_strdup(mem_ctx, ptr);
1533 /********************************************************************************
1534 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1535 string in the form of
1536 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1537 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1538 <Default Data Type>:<Comma Separated list of Files>
1539 *******************************************************************************/
1541 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1546 char *saveptr = NULL;
1547 struct spoolss_StringArray *deps;
1548 const char **file_array = NULL;
1551 /* fill in the UNISTR fields */
1552 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1553 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1554 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1555 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1556 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1557 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1558 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1560 /* <Comma Separated List of Dependent Files> */
1561 /* save the beginning of the string */
1562 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1565 /* begin to strip out each filename */
1566 str = strtok_r(str, ",", &saveptr);
1568 /* no dependent files, we are done */
1573 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1578 while (str != NULL) {
1579 add_string_to_array(deps, str, &file_array, &count);
1580 str = strtok_r(NULL, ",", &saveptr);
1583 deps->string = talloc_zero_array(deps, const char *, count + 1);
1584 if (!deps->string) {
1588 for (i=0; i < count; i++) {
1589 deps->string[i] = file_array[i];
1592 r->dependent_files = deps;
1597 /****************************************************************************
1598 ****************************************************************************/
1600 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1601 TALLOC_CTX *mem_ctx,
1602 int argc, const char **argv)
1607 struct spoolss_AddDriverInfoCtr info_ctr;
1608 struct spoolss_AddDriverInfo3 info3;
1612 /* parse the command arguments */
1613 if (argc != 3 && argc != 4)
1615 printf ("Usage: %s <Environment> \\\n", argv[0]);
1616 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1617 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1618 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1619 printf ("\t[version]\n");
1624 /* Fill in the spoolss_AddDriverInfo3 struct */
1627 arch = cmd_spoolss_get_short_archi(argv[1]);
1629 printf ("Error Unknown architechture [%s]\n", argv[1]);
1630 return WERR_INVALID_PARAM;
1633 set_drv_info_3_env(mem_ctx, &info3, arch);
1635 driver_args = talloc_strdup( mem_ctx, argv[2] );
1636 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1638 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1639 return WERR_INVALID_PARAM;
1642 /* if printer driver version specified, override the default version
1643 * used by the architecture. This allows installation of Windows
1644 * 2000 (version 3) printer drivers. */
1647 info3.version = atoi(argv[3]);
1651 info_ctr.level = level;
1652 info_ctr.info.info3 = &info3;
1654 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1655 cli->srv_name_slash,
1658 if (!NT_STATUS_IS_OK(status)) {
1659 return ntstatus_to_werror(status);
1661 if (W_ERROR_IS_OK(result)) {
1662 printf ("Printer Driver %s successfully installed.\n",
1670 /****************************************************************************
1671 ****************************************************************************/
1673 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1674 TALLOC_CTX *mem_ctx,
1675 int argc, const char **argv)
1678 struct spoolss_SetPrinterInfoCtr info_ctr;
1679 struct spoolss_SetPrinterInfo2 info2;
1681 /* parse the command arguments */
1684 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1688 /* Fill in the DRIVER_INFO_2 struct */
1691 info2.printername = argv[1];
1692 info2.drivername = argv[3];
1693 info2.sharename = argv[2];
1694 info2.portname = argv[4];
1695 info2.comment = "Created by rpcclient";
1696 info2.printprocessor = "winprint";
1697 info2.datatype = "RAW";
1698 info2.devmode = NULL;
1699 info2.secdesc = NULL;
1700 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1702 info2.defaultpriority = 0;
1703 info2.starttime = 0;
1704 info2.untiltime = 0;
1706 /* These three fields must not be used by AddPrinter()
1707 as defined in the MS Platform SDK documentation..
1711 info2.averageppm = 0;
1715 info_ctr.info.info2 = &info2;
1717 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1719 if (W_ERROR_IS_OK(result))
1720 printf ("Printer %s successfully installed.\n", argv[1]);
1725 /****************************************************************************
1726 ****************************************************************************/
1728 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1729 TALLOC_CTX *mem_ctx,
1730 int argc, const char **argv)
1732 struct policy_handle pol;
1736 const char *printername;
1737 union spoolss_PrinterInfo info;
1738 struct spoolss_SetPrinterInfoCtr info_ctr;
1739 struct spoolss_DevmodeContainer devmode_ctr;
1740 struct sec_desc_buf secdesc_ctr;
1742 ZERO_STRUCT(devmode_ctr);
1743 ZERO_STRUCT(secdesc_ctr);
1745 /* parse the command arguments */
1748 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1752 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1754 /* Get a printer handle */
1756 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1760 if (!W_ERROR_IS_OK(result))
1763 /* Get printer info */
1765 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1770 if (!W_ERROR_IS_OK(result)) {
1771 printf ("Unable to retrieve printer information!\n");
1775 /* Set the printer driver */
1777 info.info2.drivername = argv[2];
1778 info.info2.devmode = NULL;
1779 info.info2.secdesc = NULL;
1782 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
1784 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1791 if (!W_ERROR_IS_OK(result)) {
1792 printf("SetPrinter call failed!\n");
1796 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1801 if (is_valid_policy_hnd(&pol))
1802 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1808 /****************************************************************************
1809 ****************************************************************************/
1811 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1812 TALLOC_CTX *mem_ctx,
1813 int argc, const char **argv)
1815 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1821 const char *arch = NULL;
1822 uint32_t delete_flags = 0;
1824 /* parse the command arguments */
1825 if (argc < 2 || argc > 4) {
1826 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1833 vers = atoi (argv[3]);
1836 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1839 /* delete the driver for all architectures */
1840 for (i=0; archi_table[i].long_archi; i++) {
1842 if (arch && !strequal( archi_table[i].long_archi, arch))
1845 if (vers >= 0 && archi_table[i].version != vers)
1848 /* make the call to remove the driver */
1849 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1850 cli->srv_name_slash,
1851 archi_table[i].long_archi,
1854 archi_table[i].version,
1857 if ( !W_ERROR_IS_OK(result) )
1859 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1860 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1861 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1866 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1867 archi_table[i].long_archi, archi_table[i].version);
1876 /****************************************************************************
1877 ****************************************************************************/
1879 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1880 TALLOC_CTX *mem_ctx,
1881 int argc, const char **argv)
1883 WERROR result = WERR_OK;
1887 /* parse the command arguments */
1889 printf ("Usage: %s <driver>\n", argv[0]);
1893 /* delete the driver for all architectures */
1894 for (i=0; archi_table[i].long_archi; i++) {
1895 /* make the call to remove the driver */
1896 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1897 cli->srv_name_slash,
1898 archi_table[i].long_archi,
1901 if (!NT_STATUS_IS_OK(status)) {
1904 if ( !W_ERROR_IS_OK(result) ) {
1905 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1906 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1907 argv[1], archi_table[i].long_archi,
1911 printf ("Driver %s removed for arch [%s].\n", argv[1],
1912 archi_table[i].long_archi);
1919 /****************************************************************************
1920 ****************************************************************************/
1922 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1923 TALLOC_CTX *mem_ctx,
1924 int argc, const char **argv)
1928 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1931 union spoolss_PrintProcessorDirectoryInfo info;
1934 /* parse the command arguments */
1936 printf ("Usage: %s [environment]\n", argv[0]);
1941 environment = argv[1];
1944 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1945 cli->srv_name_slash,
1953 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1955 buffer = data_blob_talloc_zero(mem_ctx, needed);
1957 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1958 cli->srv_name_slash,
1968 if (W_ERROR_IS_OK(result)) {
1969 printf("%s\n", info.info1.directory_name);
1975 /****************************************************************************
1976 ****************************************************************************/
1978 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1979 int argc, const char **argv)
1981 struct policy_handle handle;
1984 const char *printername;
1985 union spoolss_AddFormInfo info;
1986 struct spoolss_AddFormInfo1 info1;
1987 struct spoolss_AddFormInfo2 info2;
1990 /* Parse the command arguments */
1992 if (argc < 3 || argc > 5) {
1993 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
1997 /* Get a printer handle */
1999 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2001 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2005 if (!W_ERROR_IS_OK(werror))
2008 /* Dummy up some values for the form data */
2011 level = atoi(argv[3]);
2016 info1.flags = SPOOLSS_FORM_USER;
2017 info1.form_name = argv[2];
2018 info1.size.width = 100;
2019 info1.size.height = 100;
2020 info1.area.left = 0;
2021 info1.area.top = 10;
2022 info1.area.right = 20;
2023 info1.area.bottom = 30;
2025 info.info1 = &info1;
2029 info2.flags = SPOOLSS_FORM_USER;
2030 info2.form_name = argv[2];
2031 info2.size.width = 100;
2032 info2.size.height = 100;
2033 info2.area.left = 0;
2034 info2.area.top = 10;
2035 info2.area.right = 20;
2036 info2.area.bottom = 30;
2037 info2.keyword = argv[2];
2038 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2039 info2.mui_dll = NULL;
2040 info2.ressource_id = 0;
2041 info2.display_name = argv[2];
2044 info.info2 = &info2;
2052 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2059 if (is_valid_policy_hnd(&handle))
2060 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2065 /****************************************************************************
2066 ****************************************************************************/
2068 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2069 int argc, const char **argv)
2071 struct policy_handle handle;
2074 const char *printername;
2075 union spoolss_AddFormInfo info;
2076 struct spoolss_AddFormInfo1 info1;
2078 /* Parse the command arguments */
2081 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2085 /* Get a printer handle */
2087 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2089 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2091 SEC_FLAG_MAXIMUM_ALLOWED,
2093 if (!W_ERROR_IS_OK(werror))
2096 /* Dummy up some values for the form data */
2098 info1.flags = SPOOLSS_FORM_PRINTER;
2099 info1.size.width = 100;
2100 info1.size.height = 100;
2101 info1.area.left = 0;
2102 info1.area.top = 1000;
2103 info1.area.right = 2000;
2104 info1.area.bottom = 3000;
2105 info1.form_name = argv[2];
2107 info.info1 = &info1;
2111 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2119 if (is_valid_policy_hnd(&handle))
2120 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2125 /****************************************************************************
2126 ****************************************************************************/
2128 static const char *get_form_flag(int form_flag)
2130 switch (form_flag) {
2131 case SPOOLSS_FORM_USER:
2133 case SPOOLSS_FORM_BUILTIN:
2134 return "FORM_BUILTIN";
2135 case SPOOLSS_FORM_PRINTER:
2136 return "FORM_PRINTER";
2142 /****************************************************************************
2143 ****************************************************************************/
2145 static void display_form_info1(struct spoolss_FormInfo1 *r)
2148 "\tflag: %s (%d)\n" \
2149 "\twidth: %d, length: %d\n" \
2150 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2151 r->form_name, get_form_flag(r->flags), r->flags,
2152 r->size.width, r->size.height,
2153 r->area.left, r->area.right,
2154 r->area.top, r->area.bottom);
2157 /****************************************************************************
2158 ****************************************************************************/
2160 static void display_form_info2(struct spoolss_FormInfo2 *r)
2163 "\tflag: %s (%d)\n" \
2164 "\twidth: %d, length: %d\n" \
2165 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2166 r->form_name, get_form_flag(r->flags), r->flags,
2167 r->size.width, r->size.height,
2168 r->area.left, r->area.right,
2169 r->area.top, r->area.bottom);
2170 printf("\tkeyword: %s\n", r->keyword);
2171 printf("\tstring_type: 0x%08x\n", r->string_type);
2172 printf("\tmui_dll: %s\n", r->mui_dll);
2173 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2174 printf("\tdisplay_name: %s\n", r->display_name);
2175 printf("\tlang_id: %d\n", r->lang_id);
2179 /****************************************************************************
2180 ****************************************************************************/
2182 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2183 int argc, const char **argv)
2185 struct policy_handle handle;
2188 const char *printername;
2190 uint32_t offered = 0;
2191 union spoolss_FormInfo info;
2195 /* Parse the command arguments */
2197 if (argc < 3 || argc > 5) {
2198 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2202 /* Get a printer handle */
2204 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2206 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2208 SEC_FLAG_MAXIMUM_ALLOWED,
2210 if (!W_ERROR_IS_OK(werror))
2214 level = atoi(argv[3]);
2219 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2228 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2229 buffer = data_blob_talloc_zero(mem_ctx, needed);
2231 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2242 if (!NT_STATUS_IS_OK(status)) {
2248 display_form_info1(&info.info1);
2251 display_form_info2(&info.info2);
2256 if (is_valid_policy_hnd(&handle))
2257 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2262 /****************************************************************************
2263 ****************************************************************************/
2265 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2266 TALLOC_CTX *mem_ctx, int argc,
2269 struct policy_handle handle;
2272 const char *printername;
2274 /* Parse the command arguments */
2277 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2281 /* Get a printer handle */
2283 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2285 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2287 SEC_FLAG_MAXIMUM_ALLOWED,
2289 if (!W_ERROR_IS_OK(werror))
2292 /* Delete the form */
2294 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2298 if (!NT_STATUS_IS_OK(status)) {
2299 return ntstatus_to_werror(status);
2303 if (is_valid_policy_hnd(&handle))
2304 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2309 /****************************************************************************
2310 ****************************************************************************/
2312 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2313 TALLOC_CTX *mem_ctx, int argc,
2316 struct policy_handle handle;
2318 const char *printername;
2319 uint32_t num_forms, level = 1, i;
2320 union spoolss_FormInfo *forms;
2322 /* Parse the command arguments */
2324 if (argc < 2 || argc > 4) {
2325 printf ("Usage: %s <printer> [level]\n", argv[0]);
2329 /* Get a printer handle */
2331 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2333 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2335 SEC_FLAG_MAXIMUM_ALLOWED,
2337 if (!W_ERROR_IS_OK(werror))
2341 level = atoi(argv[2]);
2344 /* Enumerate forms */
2346 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2353 if (!W_ERROR_IS_OK(werror))
2356 /* Display output */
2358 for (i = 0; i < num_forms; i++) {
2361 display_form_info1(&forms[i].info1);
2364 display_form_info2(&forms[i].info2);
2370 if (is_valid_policy_hnd(&handle))
2371 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2376 /****************************************************************************
2377 ****************************************************************************/
2379 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2380 TALLOC_CTX *mem_ctx,
2381 int argc, const char **argv)
2385 const char *printername;
2386 struct policy_handle pol;
2387 union spoolss_PrinterInfo info;
2388 enum winreg_Type type;
2389 union spoolss_PrinterData data;
2391 /* parse the command arguments */
2393 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2394 " <value> <data>\n",
2396 result = WERR_INVALID_PARAM;
2400 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2404 if (strequal(argv[2], "string")) {
2408 if (strequal(argv[2], "binary")) {
2412 if (strequal(argv[2], "dword")) {
2416 if (strequal(argv[2], "multistring")) {
2417 type = REG_MULTI_SZ;
2420 if (type == REG_NONE) {
2421 printf("Unknown data type: %s\n", argv[2]);
2422 result = WERR_INVALID_PARAM;
2426 /* get a printer handle */
2428 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2430 SEC_FLAG_MAXIMUM_ALLOWED,
2432 if (!W_ERROR_IS_OK(result)) {
2436 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2441 if (!W_ERROR_IS_OK(result)) {
2445 printf("%s\n", current_timestring(mem_ctx, true));
2446 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2448 /* Set the printer data */
2452 data.string = talloc_strdup(mem_ctx, argv[4]);
2453 W_ERROR_HAVE_NO_MEMORY(data.string);
2456 data.value = strtoul(argv[4], NULL, 10);
2459 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2461 case REG_MULTI_SZ: {
2463 const char **strings = NULL;
2465 for (i=4; i<argc; i++) {
2466 if (strcmp(argv[i], "NULL") == 0) {
2469 if (!add_string_to_array(mem_ctx, argv[i],
2472 result = WERR_NOMEM;
2476 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2477 if (!data.string_array) {
2478 result = WERR_NOMEM;
2481 for (i=0; i < num_strings; i++) {
2482 data.string_array[i] = strings[i];
2487 printf("Unknown data type: %s\n", argv[2]);
2488 result = WERR_INVALID_PARAM;
2492 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2494 argv[3], /* value_name */
2497 0, /* autocalculated size */
2499 if (!W_ERROR_IS_OK(result)) {
2500 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2503 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2505 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2510 if (!W_ERROR_IS_OK(result)) {
2514 printf("%s\n", current_timestring(mem_ctx, true));
2515 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2519 if (is_valid_policy_hnd(&pol)) {
2520 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2526 /****************************************************************************
2527 ****************************************************************************/
2529 static void display_job_info1(struct spoolss_JobInfo1 *r)
2531 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2532 r->user_name, r->document_name, r->text_status, r->pages_printed,
2536 /****************************************************************************
2537 ****************************************************************************/
2539 static void display_job_info2(struct spoolss_JobInfo2 *r)
2541 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2542 r->position, r->job_id,
2543 r->user_name, r->document_name, r->text_status, r->pages_printed,
2544 r->total_pages, r->size);
2547 /****************************************************************************
2548 ****************************************************************************/
2550 static void display_job_info3(struct spoolss_JobInfo3 *r)
2552 printf("jobid[%d], next_jobid[%d]\n",
2553 r->job_id, r->next_job_id);
2556 /****************************************************************************
2557 ****************************************************************************/
2559 static void display_job_info4(struct spoolss_JobInfo4 *r)
2561 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2562 r->position, r->job_id,
2563 r->user_name, r->document_name, r->text_status, r->pages_printed,
2564 r->total_pages, r->size, r->size_high);
2567 /****************************************************************************
2568 ****************************************************************************/
2570 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2571 TALLOC_CTX *mem_ctx, int argc,
2575 uint32_t level = 1, count, i;
2576 const char *printername;
2577 struct policy_handle hnd;
2578 union spoolss_JobInfo *info;
2580 if (argc < 2 || argc > 3) {
2581 printf("Usage: %s printername [level]\n", argv[0]);
2586 level = atoi(argv[2]);
2589 /* Open printer handle */
2591 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2593 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2595 SEC_FLAG_MAXIMUM_ALLOWED,
2597 if (!W_ERROR_IS_OK(result))
2600 /* Enumerate ports */
2602 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2610 if (!W_ERROR_IS_OK(result)) {
2614 for (i = 0; i < count; i++) {
2617 display_job_info1(&info[i].info1);
2620 display_job_info2(&info[i].info2);
2623 d_printf("unknown info level %d\n", level);
2629 if (is_valid_policy_hnd(&hnd)) {
2630 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2636 /****************************************************************************
2637 ****************************************************************************/
2639 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2640 TALLOC_CTX *mem_ctx, int argc,
2644 const char *printername;
2645 struct policy_handle hnd;
2648 union spoolss_JobInfo info;
2650 if (argc < 3 || argc > 4) {
2651 printf("Usage: %s printername job_id [level]\n", argv[0]);
2655 job_id = atoi(argv[2]);
2658 level = atoi(argv[3]);
2661 /* Open printer handle */
2663 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2665 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2667 SEC_FLAG_MAXIMUM_ALLOWED,
2669 if (!W_ERROR_IS_OK(result)) {
2673 /* Enumerate ports */
2675 result = rpccli_spoolss_getjob(cli, mem_ctx,
2682 if (!W_ERROR_IS_OK(result)) {
2688 display_job_info1(&info.info1);
2691 display_job_info2(&info.info2);
2694 display_job_info3(&info.info3);
2697 display_job_info4(&info.info4);
2700 d_printf("unknown info level %d\n", level);
2705 if (is_valid_policy_hnd(&hnd)) {
2706 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2712 /****************************************************************************
2713 ****************************************************************************/
2715 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2716 TALLOC_CTX *mem_ctx, int argc,
2721 const char *printername;
2722 struct policy_handle hnd;
2724 enum spoolss_JobControl command;
2727 printf("Usage: %s printername job_id command\n", argv[0]);
2731 job_id = atoi(argv[2]);
2732 command = atoi(argv[3]);
2734 /* Open printer handle */
2736 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2738 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2740 SEC_FLAG_MAXIMUM_ALLOWED,
2742 if (!W_ERROR_IS_OK(result)) {
2748 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2755 if (!W_ERROR_IS_OK(result)) {
2760 if (is_valid_policy_hnd(&hnd)) {
2761 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2767 /****************************************************************************
2768 ****************************************************************************/
2770 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2771 TALLOC_CTX *mem_ctx, int argc,
2777 const char *printername;
2778 struct policy_handle hnd;
2779 uint32_t value_offered = 0;
2780 const char *value_name = NULL;
2781 uint32_t value_needed;
2782 enum winreg_Type type;
2783 uint8_t *data = NULL;
2784 uint32_t data_offered = 0;
2785 uint32_t data_needed;
2788 printf("Usage: %s printername\n", argv[0]);
2792 /* Open printer handle */
2794 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2796 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2798 SEC_FLAG_MAXIMUM_ALLOWED,
2800 if (!W_ERROR_IS_OK(result)) {
2804 /* Enumerate data */
2806 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2818 data_offered = data_needed;
2819 value_offered = value_needed;
2820 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2821 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2823 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2825 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2836 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2837 struct regval_blob v;
2838 fstrcpy(v.valuename, value_name);
2840 v.size = data_offered;
2842 display_reg_value(v);
2846 if (W_ERROR_V(result) == ERRnomoreitems) {
2847 result = W_ERROR(ERRsuccess);
2851 if (is_valid_policy_hnd(&hnd)) {
2852 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2858 /****************************************************************************
2859 ****************************************************************************/
2861 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2862 TALLOC_CTX *mem_ctx, int argc,
2867 const char *printername;
2868 struct policy_handle hnd;
2870 struct spoolss_PrinterEnumValues *info;
2873 printf("Usage: %s printername <keyname>\n", argv[0]);
2877 /* Open printer handle */
2879 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2881 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2883 SEC_FLAG_MAXIMUM_ALLOWED,
2885 if (!W_ERROR_IS_OK(result)) {
2889 /* Enumerate subkeys */
2891 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
2897 if (!W_ERROR_IS_OK(result)) {
2901 for (i=0; i < count; i++) {
2902 display_printer_data(info[i].value_name,
2908 if (is_valid_policy_hnd(&hnd)) {
2909 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2915 /****************************************************************************
2916 ****************************************************************************/
2918 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
2919 TALLOC_CTX *mem_ctx, int argc,
2923 const char *printername;
2924 const char *keyname = NULL;
2925 struct policy_handle hnd;
2926 const char **key_buffer = NULL;
2929 if (argc < 2 || argc > 3) {
2930 printf("Usage: %s printername [keyname]\n", argv[0]);
2940 /* Open printer handle */
2942 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2944 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2946 SEC_FLAG_MAXIMUM_ALLOWED,
2948 if (!W_ERROR_IS_OK(result)) {
2952 /* Enumerate subkeys */
2954 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
2960 if (!W_ERROR_IS_OK(result)) {
2964 for (i=0; key_buffer && key_buffer[i]; i++) {
2965 printf("%s\n", key_buffer[i]);
2970 if (is_valid_policy_hnd(&hnd)) {
2971 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2977 /****************************************************************************
2978 ****************************************************************************/
2980 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2981 TALLOC_CTX *mem_ctx, int argc,
2984 const char *printername;
2985 const char *clientname;
2986 struct policy_handle hnd;
2989 struct spoolss_NotifyOption option;
2992 printf("Usage: %s printername\n", argv[0]);
2999 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3001 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3003 SEC_FLAG_MAXIMUM_ALLOWED,
3005 if (!W_ERROR_IS_OK(result)) {
3006 printf("Error opening %s\n", argv[1]);
3010 /* Create spool options */
3015 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3016 if (option.types == NULL) {
3017 result = WERR_NOMEM;
3021 option.types[0].type = PRINTER_NOTIFY_TYPE;
3022 option.types[0].count = 1;
3023 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3024 if (option.types[0].fields == NULL) {
3025 result = WERR_NOMEM;
3028 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3030 option.types[1].type = JOB_NOTIFY_TYPE;
3031 option.types[1].count = 1;
3032 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3033 if (option.types[1].fields == NULL) {
3034 result = WERR_NOMEM;
3037 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3039 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3041 result = WERR_NOMEM;
3047 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3055 if (!W_ERROR_IS_OK(result)) {
3056 printf("Error rffpcnex %s\n", argv[1]);
3061 if (is_valid_policy_hnd(&hnd))
3062 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3067 /****************************************************************************
3068 ****************************************************************************/
3070 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3071 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3073 union spoolss_PrinterInfo info1, info2;
3075 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3077 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3078 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3083 if ( !W_ERROR_IS_OK(werror) ) {
3084 printf("failed (%s)\n", win_errstr(werror));
3085 talloc_destroy(mem_ctx);
3090 printf("Retrieving printer properties for %s...", cli2->desthost);
3091 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3096 if ( !W_ERROR_IS_OK(werror) ) {
3097 printf("failed (%s)\n", win_errstr(werror));
3098 talloc_destroy(mem_ctx);
3103 talloc_destroy(mem_ctx);
3108 /****************************************************************************
3109 ****************************************************************************/
3111 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3112 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3114 union spoolss_PrinterInfo info1, info2;
3116 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3117 SEC_DESC *sd1, *sd2;
3121 printf("Retrieving printer security for %s...", cli1->desthost);
3122 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3127 if ( !W_ERROR_IS_OK(werror) ) {
3128 printf("failed (%s)\n", win_errstr(werror));
3134 printf("Retrieving printer security for %s...", cli2->desthost);
3135 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3140 if ( !W_ERROR_IS_OK(werror) ) {
3141 printf("failed (%s)\n", win_errstr(werror));
3150 sd1 = info1.info3.secdesc;
3151 sd2 = info2.info3.secdesc;
3153 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3154 printf("NULL secdesc!\n");
3159 if (!security_descriptor_equal( sd1, sd2 ) ) {
3160 printf("Security Descriptors *not* equal!\n");
3165 printf("Security descriptors match\n");
3168 talloc_destroy(mem_ctx);
3173 /****************************************************************************
3174 ****************************************************************************/
3176 extern struct user_auth_info *rpcclient_auth_info;
3178 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3179 TALLOC_CTX *mem_ctx, int argc,
3182 const char *printername;
3183 char *printername_path = NULL;
3184 struct cli_state *cli_server2 = NULL;
3185 struct rpc_pipe_client *cli2 = NULL;
3186 struct policy_handle hPrinter1, hPrinter2;
3191 printf("Usage: %s <printer> <server>\n", argv[0]);
3195 printername = argv[1];
3197 /* first get the connection to the remote server */
3199 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3202 get_cmdline_auth_info_username(rpcclient_auth_info),
3204 get_cmdline_auth_info_password(rpcclient_auth_info),
3205 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3206 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3208 if ( !NT_STATUS_IS_OK(nt_status) )
3209 return WERR_GENERAL_FAILURE;
3211 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3213 if (!NT_STATUS_IS_OK(nt_status)) {
3214 printf("failed to open spoolss pipe on server %s (%s)\n",
3215 argv[2], nt_errstr(nt_status));
3216 return WERR_GENERAL_FAILURE;
3219 /* now open up both printers */
3221 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3223 printf("Opening %s...", printername_path);
3225 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3229 if ( !W_ERROR_IS_OK(werror) ) {
3230 printf("failed (%s)\n", win_errstr(werror));
3235 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3237 printf("Opening %s...", printername_path);
3238 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3242 if ( !W_ERROR_IS_OK(werror) ) {
3243 printf("failed (%s)\n", win_errstr(werror));
3248 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3249 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3251 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3258 printf("Closing printers...");
3259 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3260 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3263 /* close the second remote connection */
3265 cli_shutdown( cli_server2 );
3269 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3271 printf("print_processor_name: %s\n", r->print_processor_name);
3274 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3275 TALLOC_CTX *mem_ctx, int argc,
3279 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3280 uint32_t num_procs, level = 1, i;
3281 union spoolss_PrintProcessorInfo *procs;
3283 /* Parse the command arguments */
3285 if (argc < 1 || argc > 4) {
3286 printf ("Usage: %s [environment] [level]\n", argv[0]);
3291 environment = argv[1];
3295 level = atoi(argv[2]);
3298 /* Enumerate Print Processors */
3300 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3301 cli->srv_name_slash,
3307 if (!W_ERROR_IS_OK(werror))
3310 /* Display output */
3312 for (i = 0; i < num_procs; i++) {
3315 display_proc_info1(&procs[i].info1);
3324 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3326 printf("name_array: %s\n", r->name_array);
3329 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3330 TALLOC_CTX *mem_ctx, int argc,
3334 const char *print_processor_name = "winprint";
3335 uint32_t num_procs, level = 1, i;
3336 union spoolss_PrintProcDataTypesInfo *procs;
3338 /* Parse the command arguments */
3340 if (argc < 1 || argc > 4) {
3341 printf ("Usage: %s [environment] [level]\n", argv[0]);
3346 print_processor_name = argv[1];
3350 level = atoi(argv[2]);
3353 /* Enumerate Print Processor Data Types */
3355 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3356 cli->srv_name_slash,
3357 print_processor_name,
3362 if (!W_ERROR_IS_OK(werror))
3365 /* Display output */
3367 for (i = 0; i < num_procs; i++) {
3370 display_proc_data_types_info1(&procs[i].info1);
3379 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3381 printf("monitor_name: %s\n", r->monitor_name);
3384 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3386 printf("monitor_name: %s\n", r->monitor_name);
3387 printf("environment: %s\n", r->environment);
3388 printf("dll_name: %s\n", r->dll_name);
3391 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3392 TALLOC_CTX *mem_ctx, int argc,
3396 uint32_t count, level = 1, i;
3397 union spoolss_MonitorInfo *info;
3399 /* Parse the command arguments */
3402 printf("Usage: %s [level]\n", argv[0]);
3407 level = atoi(argv[1]);
3410 /* Enumerate Print Monitors */
3412 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3413 cli->srv_name_slash,
3418 if (!W_ERROR_IS_OK(werror)) {
3422 /* Display output */
3424 for (i = 0; i < count; i++) {
3427 display_monitor1(&info[i].info1);
3430 display_monitor2(&info[i].info2);
3439 /* List of commands exported by this module */
3440 struct cmd_set spoolss_commands[] = {
3444 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3445 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3446 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3447 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3448 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3449 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3450 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3451 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3452 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3453 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3454 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3455 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3456 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3457 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3458 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3459 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3460 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3461 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3462 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3463 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3464 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3465 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3466 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3467 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3468 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3469 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3470 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3471 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3472 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3473 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3474 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3475 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3476 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3477 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },