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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpcclient.h"
28 const char *long_archi;
29 const char *short_archi;
33 /* The version int is used by getdrivers. Note that
34 all architecture strings that support mutliple
35 versions must be grouped together since enumdrivers
36 uses this property to prevent issuing multiple
37 enumdriver calls for the same arch */
40 static const struct table_node archi_table[]= {
42 {"Windows 4.0", "WIN40", 0 },
43 {"Windows NT x86", "W32X86", 2 },
44 {"Windows NT x86", "W32X86", 3 },
45 {"Windows NT R4000", "W32MIPS", 2 },
46 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
47 {"Windows NT PowerPC", "W32PPC", 2 },
48 {"Windows IA64", "IA64", 3 },
49 {"Windows x64", "x64", 3 },
56 * rpcclient module for SPOOLSS rpc pipe.
58 * This generally just parses and checks command lines, and then calls
59 * a cli_spoolss function.
62 /****************************************************************************
63 function to do the mapping between the long architecture name and
65 ****************************************************************************/
67 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
71 DEBUG(107,("Getting architecture dependant directory\n"));
74 } while ( (archi_table[i].long_archi!=NULL ) &&
75 StrCaseCmp(long_archi, archi_table[i].long_archi) );
77 if (archi_table[i].long_archi==NULL) {
78 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
82 /* this might be client code - but shouldn't this be an fstrcpy etc? */
85 DEBUGADD(108,("index: [%d]\n", i));
86 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
87 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
89 return archi_table[i].short_archi;
92 /****************************************************************************
93 ****************************************************************************/
95 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
97 int argc, const char **argv)
101 fstring servername, user;
105 printf("Usage: %s <printername>\n", argv[0]);
110 return WERR_GENERAL_FAILURE;
112 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
113 strupper_m(servername);
114 fstrcpy(user, cli->auth->user_name);
115 fstrcpy(printername, argv[1]);
117 /* Open the printer handle */
119 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
120 "", PRINTER_ALL_ACCESS,
121 servername, user, &hnd);
123 if (W_ERROR_IS_OK(werror)) {
124 printf("Printer %s opened successfully\n", printername);
125 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
127 if (!W_ERROR_IS_OK(werror)) {
128 printf("Error closing printer handle! (%s)\n",
129 get_dos_error_msg(werror));
137 /****************************************************************************
138 ****************************************************************************/
140 static void display_print_info_0(PRINTER_INFO_0 *i0)
143 fstring servername = "";
148 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
150 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
152 printf("\tprintername:[%s]\n", name);
153 printf("\tservername:[%s]\n", servername);
154 printf("\tcjobs:[0x%x]\n", i0->cjobs);
155 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
157 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
158 i0->day, i0->dayofweek);
159 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
160 i0->second, i0->milliseconds);
162 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
163 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
165 printf("\tmajorversion:[0x%x]\n", i0->major_version);
166 printf("\tbuildversion:[0x%x]\n", i0->build_version);
168 printf("\tunknown7:[0x%x]\n", i0->unknown7);
169 printf("\tunknown8:[0x%x]\n", i0->unknown8);
170 printf("\tunknown9:[0x%x]\n", i0->unknown9);
171 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
172 printf("\tunknown11:[0x%x]\n", i0->unknown11);
173 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
174 printf("\tunknown13:[0x%x]\n", i0->unknown13);
175 printf("\tunknown14:[0x%x]\n", i0->unknown14);
176 printf("\tunknown15:[0x%x]\n", i0->unknown15);
177 printf("\tunknown16:[0x%x]\n", i0->unknown16);
178 printf("\tchange_id:[0x%x]\n", i0->change_id);
179 printf("\tunknown18:[0x%x]\n", i0->unknown18);
180 printf("\tstatus:[0x%x]\n", i0->status);
181 printf("\tunknown20:[0x%x]\n", i0->unknown20);
182 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
183 printf("\tunknown22:[0x%x]\n", i0->unknown22);
184 printf("\tunknown23:[0x%x]\n", i0->unknown23);
185 printf("\tunknown24:[0x%x]\n", i0->unknown24);
186 printf("\tunknown25:[0x%x]\n", i0->unknown25);
187 printf("\tunknown26:[0x%x]\n", i0->unknown26);
188 printf("\tunknown27:[0x%x]\n", i0->unknown27);
189 printf("\tunknown28:[0x%x]\n", i0->unknown28);
190 printf("\tunknown29:[0x%x]\n", i0->unknown29);
195 /****************************************************************************
196 ****************************************************************************/
198 static void display_print_info_1(PRINTER_INFO_1 *i1)
204 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
207 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
208 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
210 printf("\tflags:[0x%x]\n", i1->flags);
211 printf("\tname:[%s]\n", name);
212 printf("\tdescription:[%s]\n", desc);
213 printf("\tcomment:[%s]\n", comm);
218 /****************************************************************************
219 ****************************************************************************/
221 static void display_print_info_2(PRINTER_INFO_2 *i2)
223 fstring servername = "";
224 fstring printername = "";
225 fstring sharename = "";
226 fstring portname = "";
227 fstring drivername = "";
228 fstring comment = "";
229 fstring location = "";
230 fstring sepfile = "";
231 fstring printprocessor = "";
232 fstring datatype = "";
233 fstring parameters = "";
235 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
236 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
237 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
238 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
239 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
240 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
241 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
242 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
243 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
244 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
245 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
247 printf("\tservername:[%s]\n", servername);
248 printf("\tprintername:[%s]\n", printername);
249 printf("\tsharename:[%s]\n", sharename);
250 printf("\tportname:[%s]\n", portname);
251 printf("\tdrivername:[%s]\n", drivername);
252 printf("\tcomment:[%s]\n", comment);
253 printf("\tlocation:[%s]\n", location);
254 printf("\tsepfile:[%s]\n", sepfile);
255 printf("\tprintprocessor:[%s]\n", printprocessor);
256 printf("\tdatatype:[%s]\n", datatype);
257 printf("\tparameters:[%s]\n", parameters);
258 printf("\tattributes:[0x%x]\n", i2->attributes);
259 printf("\tpriority:[0x%x]\n", i2->priority);
260 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
261 printf("\tstarttime:[0x%x]\n", i2->starttime);
262 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
263 printf("\tstatus:[0x%x]\n", i2->status);
264 printf("\tcjobs:[0x%x]\n", i2->cjobs);
265 printf("\taverageppm:[0x%x]\n", i2->averageppm);
268 display_sec_desc(i2->secdesc);
273 /****************************************************************************
274 ****************************************************************************/
276 static void display_print_info_3(PRINTER_INFO_3 *i3)
278 display_sec_desc(i3->secdesc);
283 /****************************************************************************
284 ****************************************************************************/
286 static void display_print_info_7(PRINTER_INFO_7 *i7)
289 rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE);
290 printf("\tguid:[%s]\n", guid);
291 printf("\taction:[0x%x]\n", i7->action);
295 /****************************************************************************
296 ****************************************************************************/
298 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
300 int argc, const char **argv)
303 uint32 info_level = 1;
304 PRINTER_INFO_CTR ctr;
305 uint32 i = 0, num_printers;
310 printf("Usage: %s [level] [name]\n", argv[0]);
315 info_level = atoi(argv[1]);
318 fstrcpy(name, argv[2]);
320 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
326 result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
327 info_level, &num_printers, &ctr);
329 if (W_ERROR_IS_OK(result)) {
332 printf ("No printers returned.\n");
336 for (i = 0; i < num_printers; i++) {
339 display_print_info_0(&ctr.printers_0[i]);
342 display_print_info_1(&ctr.printers_1[i]);
345 display_print_info_2(&ctr.printers_2[i]);
348 display_print_info_3(&ctr.printers_3[i]);
351 printf("unknown info level %d\n", info_level);
361 /****************************************************************************
362 ****************************************************************************/
364 static void display_port_info_1(PORT_INFO_1 *i1)
368 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
369 printf("\tPort Name:\t[%s]\n", buffer);
372 /****************************************************************************
373 ****************************************************************************/
375 static void display_port_info_2(PORT_INFO_2 *i2)
379 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
380 printf("\tPort Name:\t[%s]\n", buffer);
381 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
383 printf("\tMonitor Name:\t[%s]\n", buffer);
384 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
386 printf("\tDescription:\t[%s]\n", buffer);
387 printf("\tPort Type:\t" );
388 if ( i2->port_type ) {
389 int comma = 0; /* hack */
391 if ( i2->port_type & PORT_TYPE_READ ) {
395 if ( i2->port_type & PORT_TYPE_WRITE ) {
396 printf( "%sWrite", comma ? ", " : "" );
399 /* These two have slightly different interpretations
400 on 95/98/ME but I'm disregarding that for now */
401 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
402 printf( "%sRedirected", comma ? ", " : "" );
405 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
406 printf( "%sNet-Attached", comma ? ", " : "" );
410 printf( "[Unset]\n" );
412 printf("\tReserved:\t[%d]\n", i2->reserved);
416 /****************************************************************************
417 ****************************************************************************/
419 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
420 TALLOC_CTX *mem_ctx, int argc,
424 uint32 info_level = 1;
429 printf("Usage: %s [level]\n", argv[0]);
434 info_level = atoi(argv[1]);
436 /* Enumerate ports */
440 result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
442 if (W_ERROR_IS_OK(result)) {
445 for (i = 0; i < returned; i++) {
446 switch (info_level) {
448 display_port_info_1(&ctr.port.info_1[i]);
451 display_port_info_2(&ctr.port.info_2[i]);
454 printf("unknown info level %d\n", info_level);
463 /****************************************************************************
464 ****************************************************************************/
466 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
468 int argc, const char **argv)
472 uint32 info_level = 2;
473 bool opened_hnd = False;
474 PRINTER_INFO_CTR ctr;
480 if (argc == 1 || argc > 3) {
481 printf("Usage: %s printername comment\n", argv[0]);
486 /* Open a printer handle */
488 fstrcpy(comment, argv[2]);
491 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
492 strupper_m(servername);
493 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
494 fstrcpy(user, cli->auth->user_name);
496 /* get a printer handle */
497 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
498 PRINTER_ALL_ACCESS, servername,
501 if (!W_ERROR_IS_OK(result))
506 /* Get printer info */
507 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
509 if (!W_ERROR_IS_OK(result))
513 /* Modify the comment. */
514 init_unistr(&ctr.printers_2->comment, comment);
515 ctr.printers_2->devmode = NULL;
516 ctr.printers_2->secdesc = NULL;
518 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
519 if (W_ERROR_IS_OK(result))
520 printf("Success in setting comment.\n");
524 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
529 /****************************************************************************
530 ****************************************************************************/
532 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
534 int argc, const char **argv)
538 uint32 info_level = 2;
539 bool opened_hnd = False;
540 PRINTER_INFO_CTR ctr;
546 if (argc == 1 || argc > 3) {
547 printf("Usage: %s printername new_printername\n", argv[0]);
552 /* Open a printer handle */
554 fstrcpy(new_printername, argv[2]);
557 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
558 strupper_m(servername);
559 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
560 fstrcpy(user, cli->auth->user_name);
562 /* get a printer handle */
563 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
564 PRINTER_ALL_ACCESS, servername,
567 if (!W_ERROR_IS_OK(result))
572 /* Get printer info */
573 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
575 if (!W_ERROR_IS_OK(result))
578 /* Modify the printername. */
579 init_unistr(&ctr.printers_2->printername, new_printername);
580 ctr.printers_2->devmode = NULL;
581 ctr.printers_2->secdesc = NULL;
583 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
584 if (W_ERROR_IS_OK(result))
585 printf("Success in setting printername.\n");
589 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
594 /****************************************************************************
595 ****************************************************************************/
597 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
599 int argc, const char **argv)
603 uint32 info_level = 1;
604 bool opened_hnd = False;
605 PRINTER_INFO_CTR ctr;
610 if (argc == 1 || argc > 3) {
611 printf("Usage: %s <printername> [level]\n", argv[0]);
615 /* Open a printer handle */
617 info_level = atoi(argv[2]);
620 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
621 strupper_m(servername);
622 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
623 fstrcpy(user, cli->auth->user_name);
625 /* get a printer handle */
627 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
628 "", MAXIMUM_ALLOWED_ACCESS,
629 servername, user, &pol);
631 if (!W_ERROR_IS_OK(result))
636 /* Get printer info */
638 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
640 if (!W_ERROR_IS_OK(result))
643 /* Display printer info */
645 switch (info_level) {
647 display_print_info_0(ctr.printers_0);
650 display_print_info_1(ctr.printers_1);
653 display_print_info_2(ctr.printers_2);
656 display_print_info_3(ctr.printers_3);
659 display_print_info_7(ctr.printers_7);
662 printf("unknown info level %d\n", info_level);
668 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
673 /****************************************************************************
674 ****************************************************************************/
676 static void display_reg_value(REGISTRY_VALUE value)
682 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
683 *((uint32 *) value.data_p));
686 rpcstr_pull_talloc(talloc_tos(),
691 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
694 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
696 printf("%s: REG_BINARY:", value.valuename);
698 for (i=0; i<len; i++) {
699 if (hex[i] == '\0') {
712 uint32 i, num_values;
715 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
716 value.size, &num_values,
718 d_printf("reg_pull_multi_sz failed\n");
722 for (i=0; i<num_values; i++) {
723 d_printf("%s\n", values[i]);
729 printf("%s: unknown type %d\n", value.valuename, value.type);
734 /****************************************************************************
735 ****************************************************************************/
737 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
739 int argc, const char **argv)
743 bool opened_hnd = False;
747 const char *valuename;
748 REGISTRY_VALUE value;
751 printf("Usage: %s <printername> <valuename>\n", argv[0]);
752 printf("<printername> of . queries print server\n");
757 /* Open a printer handle */
759 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
760 strupper_m(servername);
761 if (strncmp(argv[1], ".", sizeof(".")) == 0)
762 fstrcpy(printername, servername);
764 slprintf(printername, sizeof(servername)-1, "%s\\%s",
765 servername, argv[1]);
766 fstrcpy(user, cli->auth->user_name);
768 /* get a printer handle */
770 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
771 "", MAXIMUM_ALLOWED_ACCESS,
772 servername, user, &pol);
774 if (!W_ERROR_IS_OK(result))
779 /* Get printer info */
781 result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
783 if (!W_ERROR_IS_OK(result))
786 /* Display printer data */
788 fstrcpy(value.valuename, valuename);
789 display_reg_value(value);
794 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
799 /****************************************************************************
800 ****************************************************************************/
802 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
804 int argc, const char **argv)
808 bool opened_hnd = False;
812 const char *valuename, *keyname;
813 REGISTRY_VALUE value;
816 printf("Usage: %s <printername> <keyname> <valuename>\n",
818 printf("<printername> of . queries print server\n");
824 /* Open a printer handle */
826 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
827 strupper_m(servername);
828 if (strncmp(argv[1], ".", sizeof(".")) == 0)
829 fstrcpy(printername, servername);
831 slprintf(printername, sizeof(printername)-1, "%s\\%s",
832 servername, argv[1]);
833 fstrcpy(user, cli->auth->user_name);
835 /* get a printer handle */
837 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
838 "", MAXIMUM_ALLOWED_ACCESS,
839 servername, user, &pol);
841 if (!W_ERROR_IS_OK(result))
846 /* Get printer info */
848 result = rpccli_spoolss_getprinterdataex(cli, mem_ctx, &pol, keyname,
851 if (!W_ERROR_IS_OK(result))
854 /* Display printer data */
856 fstrcpy(value.valuename, valuename);
857 display_reg_value(value);
862 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
867 /****************************************************************************
868 ****************************************************************************/
870 static void display_print_driver_1(DRIVER_INFO_1 *i1)
876 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
878 printf ("Printer Driver Info 1:\n");
879 printf ("\tDriver Name: [%s]\n\n", name);
884 /****************************************************************************
885 ****************************************************************************/
887 static void display_print_driver_2(DRIVER_INFO_2 *i1)
890 fstring architecture;
897 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
898 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
899 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
900 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
901 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
903 printf ("Printer Driver Info 2:\n");
904 printf ("\tVersion: [%x]\n", i1->version);
905 printf ("\tDriver Name: [%s]\n", name);
906 printf ("\tArchitecture: [%s]\n", architecture);
907 printf ("\tDriver Path: [%s]\n", driverpath);
908 printf ("\tDatafile: [%s]\n", datafile);
909 printf ("\tConfigfile: [%s]\n\n", configfile);
914 /****************************************************************************
915 ****************************************************************************/
917 static void display_print_driver_3(DRIVER_INFO_3 *i1)
920 fstring architecture = "";
921 fstring driverpath = "";
922 fstring datafile = "";
923 fstring configfile = "";
924 fstring helpfile = "";
925 fstring dependentfiles = "";
926 fstring monitorname = "";
927 fstring defaultdatatype = "";
935 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
936 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
937 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
938 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
939 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
940 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
941 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
942 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
944 printf ("Printer Driver Info 3:\n");
945 printf ("\tVersion: [%x]\n", i1->version);
946 printf ("\tDriver Name: [%s]\n",name);
947 printf ("\tArchitecture: [%s]\n", architecture);
948 printf ("\tDriver Path: [%s]\n", driverpath);
949 printf ("\tDatafile: [%s]\n", datafile);
950 printf ("\tConfigfile: [%s]\n", configfile);
951 printf ("\tHelpfile: [%s]\n\n", helpfile);
955 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
957 length+=strlen(dependentfiles)+1;
959 if (strlen(dependentfiles) > 0)
961 printf ("\tDependentfiles: [%s]\n", dependentfiles);
971 printf ("\tMonitorname: [%s]\n", monitorname);
972 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
977 /****************************************************************************
978 ****************************************************************************/
980 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
982 int argc, const char **argv)
986 uint32 info_level = 3;
987 bool opened_hnd = False;
988 PRINTER_DRIVER_CTR ctr;
993 bool success = False;
995 if ((argc == 1) || (argc > 3))
997 printf("Usage: %s <printername> [level]\n", argv[0]);
1001 /* get the arguments need to open the printer handle */
1002 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1003 strupper_m(servername);
1004 fstrcpy(user, cli->auth->user_name);
1005 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1007 info_level = atoi(argv[2]);
1009 /* Open a printer handle */
1011 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1013 servername, user, &pol);
1015 if (!W_ERROR_IS_OK(werror)) {
1016 printf("Error opening printer handle for %s!\n", printername);
1022 /* loop through and print driver info level for each architecture */
1024 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1026 werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
1027 archi_table[i].long_archi, archi_table[i].version,
1030 if (!W_ERROR_IS_OK(werror))
1033 /* need at least one success */
1037 printf ("\n[%s]\n", archi_table[i].long_archi);
1039 switch (info_level) {
1041 display_print_driver_1 (ctr.info1);
1044 display_print_driver_2 (ctr.info2);
1047 display_print_driver_3 (ctr.info3);
1050 printf("unknown info level %d\n", info_level);
1058 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1066 /****************************************************************************
1067 ****************************************************************************/
1069 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1070 TALLOC_CTX *mem_ctx,
1071 int argc, const char **argv)
1073 WERROR werror = WERR_OK;
1074 uint32 info_level = 1;
1075 PRINTER_DRIVER_CTR ctr;
1080 printf("Usage: enumdrivers [level]\n");
1085 info_level = atoi(argv[1]);
1088 /* loop through and print driver info level for each architecture */
1089 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1090 /* check to see if we already asked for this architecture string */
1092 if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
1095 werror = rpccli_spoolss_enumprinterdrivers(
1096 cli, mem_ctx, info_level,
1097 archi_table[i].long_archi, &returned, &ctr);
1099 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1100 printf ("Server does not support environment [%s]\n",
1101 archi_table[i].long_archi);
1109 if (!W_ERROR_IS_OK(werror)) {
1110 printf ("Error getting driver for environment [%s] - %d\n",
1111 archi_table[i].long_archi, W_ERROR_V(werror));
1115 printf ("\n[%s]\n", archi_table[i].long_archi);
1120 for (j=0; j < returned; j++) {
1121 display_print_driver_1 (&ctr.info1[j]);
1125 for (j=0; j < returned; j++) {
1126 display_print_driver_2 (&ctr.info2[j]);
1130 for (j=0; j < returned; j++) {
1131 display_print_driver_3 (&ctr.info3[j]);
1135 printf("unknown info level %d\n", info_level);
1136 return WERR_UNKNOWN_LEVEL;
1143 /****************************************************************************
1144 ****************************************************************************/
1146 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1152 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1154 printf ("\tDirectory Name:[%s]\n", name);
1157 /****************************************************************************
1158 ****************************************************************************/
1160 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1161 TALLOC_CTX *mem_ctx,
1162 int argc, const char **argv)
1166 DRIVER_DIRECTORY_CTR ctr;
1169 printf("Usage: %s [environment]\n", argv[0]);
1173 /* Get the arguments need to open the printer handle */
1176 fstrcpy (env, argv[1]);
1178 fstrcpy (env, "Windows NT x86");
1180 /* Get the directory. Only use Info level 1 */
1182 result = rpccli_spoolss_getprinterdriverdir(cli, mem_ctx, 1, env, &ctr);
1184 if (W_ERROR_IS_OK(result))
1185 display_printdriverdir_1(ctr.info1);
1190 /****************************************************************************
1191 ****************************************************************************/
1193 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1198 for (i=0; archi_table[i].long_archi != NULL; i++)
1200 if (strcmp(arch, archi_table[i].short_archi) == 0)
1202 info->version = archi_table[i].version;
1203 init_unistr (&info->architecture, archi_table[i].long_archi);
1208 if (archi_table[i].long_archi == NULL)
1210 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1217 /**************************************************************************
1218 wrapper for strtok to get the next parameter from a delimited list.
1219 Needed to handle the empty parameter string denoted by "NULL"
1220 *************************************************************************/
1222 static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest,
1227 /* get the next token */
1228 ptr = strtok_r(str, delim, saveptr);
1230 /* a string of 'NULL' is used to represent an empty
1231 parameter because two consecutive delimiters
1232 will not return an empty string. See man strtok(3)
1234 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
1238 init_unistr(dest, ptr);
1243 /********************************************************************************
1244 fill in the members of a DRIVER_INFO_3 struct using a character
1245 string in the form of
1246 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1247 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1248 <Default Data Type>:<Comma Separated list of Files>
1249 *******************************************************************************/
1250 static bool init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
1255 char *saveptr = NULL;
1257 /* fill in the UNISTR fields */
1258 str = get_driver_3_param (args, ":", &info->name, &saveptr);
1259 str = get_driver_3_param (NULL, ":", &info->driverpath, &saveptr);
1260 str = get_driver_3_param (NULL, ":", &info->datafile, &saveptr);
1261 str = get_driver_3_param (NULL, ":", &info->configfile, &saveptr);
1262 str = get_driver_3_param (NULL, ":", &info->helpfile, &saveptr);
1263 str = get_driver_3_param (NULL, ":", &info->monitorname, &saveptr);
1264 str = get_driver_3_param (NULL, ":", &info->defaultdatatype, &saveptr);
1266 /* <Comma Separated List of Dependent Files> */
1267 /* save the beginning of the string */
1268 str2 = get_driver_3_param (NULL, ":", NULL, &saveptr);
1271 /* begin to strip out each filename */
1272 str = strtok_r(str, ",", &saveptr);
1276 /* keep a cumlative count of the str lengths */
1277 len += strlen(str)+1;
1278 str = strtok_r(NULL, ",", &saveptr);
1281 /* allocate the space; add one extra slot for a terminating NULL.
1282 Each filename is NULL terminated and the end contains a double
1284 if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL)
1286 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1289 for (i=0; i<len; i++)
1291 SSVAL(&info->dependentfiles[i], 0, str2[i]);
1293 info->dependentfiles[len] = '\0';
1299 /****************************************************************************
1300 ****************************************************************************/
1302 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1303 TALLOC_CTX *mem_ctx,
1304 int argc, const char **argv)
1308 PRINTER_DRIVER_CTR ctr;
1309 DRIVER_INFO_3 info3;
1311 fstring driver_name;
1314 /* parse the command arguments */
1315 if (argc != 3 && argc != 4)
1317 printf ("Usage: %s <Environment> \\\n", argv[0]);
1318 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1319 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1320 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1321 printf ("\t[version]\n");
1326 /* Fill in the DRIVER_INFO_3 struct */
1328 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
1330 printf ("Error Unknown architechture [%s]\n", argv[1]);
1331 return WERR_INVALID_PARAM;
1334 set_drv_info_3_env(&info3, arch);
1336 driver_args = talloc_strdup( mem_ctx, argv[2] );
1337 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1339 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1340 return WERR_INVALID_PARAM;
1343 /* if printer driver version specified, override the default version
1344 * used by the architecture. This allows installation of Windows
1345 * 2000 (version 3) printer drivers. */
1348 info3.version = atoi(argv[3]);
1353 result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1355 if (W_ERROR_IS_OK(result)) {
1356 rpcstr_pull(driver_name, info3.name.buffer,
1357 sizeof(driver_name), -1, STR_TERMINATE);
1358 printf ("Printer Driver %s successfully installed.\n",
1366 /****************************************************************************
1367 ****************************************************************************/
1369 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1370 TALLOC_CTX *mem_ctx,
1371 int argc, const char **argv)
1375 PRINTER_INFO_CTR ctr;
1376 PRINTER_INFO_2 info2;
1379 /* parse the command arguments */
1382 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1386 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1387 strupper_m(servername);
1389 /* Fill in the DRIVER_INFO_2 struct */
1392 init_unistr( &info2.printername, argv[1]);
1393 init_unistr( &info2.sharename, argv[2]);
1394 init_unistr( &info2.drivername, argv[3]);
1395 init_unistr( &info2.portname, argv[4]);
1396 init_unistr( &info2.comment, "Created by rpcclient");
1397 init_unistr( &info2.printprocessor, "winprint");
1398 init_unistr( &info2.datatype, "RAW");
1399 info2.devmode = NULL;
1400 info2.secdesc = NULL;
1401 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1403 info2.defaultpriority = 0;
1404 info2.starttime = 0;
1405 info2.untiltime = 0;
1407 /* These three fields must not be used by AddPrinter()
1408 as defined in the MS Platform SDK documentation..
1412 info2.averageppm = 0;
1415 ctr.printers_2 = &info2;
1416 result = rpccli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1418 if (W_ERROR_IS_OK(result))
1419 printf ("Printer %s successfully installed.\n", argv[1]);
1424 /****************************************************************************
1425 ****************************************************************************/
1427 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1428 TALLOC_CTX *mem_ctx,
1429 int argc, const char **argv)
1434 bool opened_hnd = False;
1435 PRINTER_INFO_CTR ctr;
1436 PRINTER_INFO_2 info2;
1441 /* parse the command arguments */
1444 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1448 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1449 strupper_m(servername);
1450 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1451 fstrcpy(user, cli->auth->user_name);
1453 /* Get a printer handle */
1455 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1457 servername, user, &pol);
1459 if (!W_ERROR_IS_OK(result))
1464 /* Get printer info */
1466 ZERO_STRUCT (info2);
1467 ctr.printers_2 = &info2;
1469 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
1471 if (!W_ERROR_IS_OK(result)) {
1472 printf ("Unable to retrieve printer information!\n");
1476 /* Set the printer driver */
1478 init_unistr(&ctr.printers_2->drivername, argv[2]);
1480 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1482 if (!W_ERROR_IS_OK(result)) {
1483 printf("SetPrinter call failed!\n");
1487 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1493 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1499 /****************************************************************************
1500 ****************************************************************************/
1502 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1503 TALLOC_CTX *mem_ctx,
1504 int argc, const char **argv)
1506 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1511 const char *arch = NULL;
1513 /* parse the command arguments */
1514 if (argc < 2 || argc > 4) {
1515 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1522 vers = atoi (argv[3]);
1525 /* delete the driver for all architectures */
1526 for (i=0; archi_table[i].long_archi; i++) {
1528 if (arch && !strequal( archi_table[i].long_archi, arch))
1531 if (vers >= 0 && archi_table[i].version != vers)
1534 /* make the call to remove the driver */
1535 result = rpccli_spoolss_deleteprinterdriverex(
1536 cli, mem_ctx, archi_table[i].long_archi, argv[1], archi_table[i].version);
1538 if ( !W_ERROR_IS_OK(result) )
1540 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1541 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1542 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1547 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1548 archi_table[i].long_archi, archi_table[i].version);
1557 /****************************************************************************
1558 ****************************************************************************/
1560 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1561 TALLOC_CTX *mem_ctx,
1562 int argc, const char **argv)
1564 WERROR result = WERR_OK;
1569 /* parse the command arguments */
1571 printf ("Usage: %s <driver>\n", argv[0]);
1575 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1576 strupper_m(servername);
1578 /* delete the driver for all architectures */
1579 for (i=0; archi_table[i].long_archi; i++) {
1580 /* make the call to remove the driver */
1581 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1583 archi_table[i].long_archi,
1586 if (!NT_STATUS_IS_OK(status)) {
1589 if ( !W_ERROR_IS_OK(result) ) {
1590 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1591 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1592 argv[1], archi_table[i].long_archi,
1596 printf ("Driver %s removed for arch [%s].\n", argv[1],
1597 archi_table[i].long_archi);
1604 /****************************************************************************
1605 ****************************************************************************/
1607 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1608 TALLOC_CTX *mem_ctx,
1609 int argc, const char **argv)
1612 char *servername = NULL, *environment = NULL;
1615 /* parse the command arguments */
1617 printf ("Usage: %s [environment]\n", argv[0]);
1621 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1623 strupper_m(servername);
1625 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1626 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1627 SAFE_FREE(servername);
1631 result = rpccli_spoolss_getprintprocessordirectory(
1632 cli, mem_ctx, servername, environment, procdir);
1634 if (W_ERROR_IS_OK(result))
1635 printf("%s\n", procdir);
1637 SAFE_FREE(servername);
1638 SAFE_FREE(environment);
1643 /****************************************************************************
1644 ****************************************************************************/
1646 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1647 int argc, const char **argv)
1652 char *servername = NULL, *printername = NULL;
1653 bool got_handle = False;
1654 union spoolss_AddFormInfo info;
1655 struct spoolss_AddFormInfo1 info1;
1657 /* Parse the command arguments */
1660 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1664 /* Get a printer handle */
1666 if (asprintf(&servername, "\\\\%s", cli->desthost) == -1) {
1669 strupper_m(servername);
1670 if (asprintf(&printername, "%s\\%s", servername, argv[1]) == -1) {
1671 SAFE_FREE(servername);
1675 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1677 servername, cli->auth->user_name,
1680 if (!W_ERROR_IS_OK(werror))
1685 /* Dummy up some values for the form data */
1687 info1.flags = FORM_USER;
1688 info1.form_name = argv[2];
1689 info1.size.width = 100;
1690 info1.size.height = 100;
1691 info1.area.left = 0;
1692 info1.area.top = 10;
1693 info1.area.right = 20;
1694 info1.area.bottom = 30;
1696 info.info1 = &info1;
1701 status = rpccli_spoolss_AddForm(cli, mem_ctx,
1709 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1711 SAFE_FREE(servername);
1712 SAFE_FREE(printername);
1717 /****************************************************************************
1718 ****************************************************************************/
1720 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1721 int argc, const char **argv)
1726 char *servername = NULL, *printername = NULL;
1727 bool got_handle = False;
1728 union spoolss_AddFormInfo info;
1729 struct spoolss_AddFormInfo1 info1;
1731 /* Parse the command arguments */
1734 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1738 /* Get a printer handle */
1740 if (asprintf(&servername, "\\\\%s", cli->desthost)) {
1743 strupper_m(servername);
1744 if (asprintf(&printername, "%s\\%s", servername, argv[1]) == -1) {
1745 SAFE_FREE(servername);
1749 werror = rpccli_spoolss_open_printer_ex(
1750 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1751 servername, cli->auth->user_name, &handle);
1753 if (!W_ERROR_IS_OK(werror))
1758 /* Dummy up some values for the form data */
1760 info1.flags = FORM_PRINTER;
1761 info1.size.width = 100;
1762 info1.size.height = 100;
1763 info1.area.left = 0;
1764 info1.area.top = 1000;
1765 info1.area.right = 2000;
1766 info1.area.bottom = 3000;
1767 info1.form_name = argv[2];
1769 info.info1 = &info1;
1773 status = rpccli_spoolss_SetForm(cli, mem_ctx,
1782 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1784 SAFE_FREE(servername);
1785 SAFE_FREE(printername);
1790 /****************************************************************************
1791 ****************************************************************************/
1793 static const char *get_form_flag(int form_flag)
1795 switch (form_flag) {
1799 return "FORM_BUILTIN";
1801 return "FORM_PRINTER";
1807 /****************************************************************************
1808 ****************************************************************************/
1810 static void display_form(FORM_1 *form)
1812 fstring form_name = "";
1814 if (form->name.buffer)
1815 rpcstr_pull(form_name, form->name.buffer,
1816 sizeof(form_name), -1, STR_TERMINATE);
1819 "\tflag: %s (%d)\n" \
1820 "\twidth: %d, length: %d\n" \
1821 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1822 form_name, get_form_flag(form->flag), form->flag,
1823 form->width, form->length,
1824 form->left, form->right,
1825 form->top, form->bottom);
1828 /****************************************************************************
1829 ****************************************************************************/
1831 static void display_form_info1(struct spoolss_FormInfo1 *r)
1834 "\tflag: %s (%d)\n" \
1835 "\twidth: %d, length: %d\n" \
1836 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1837 r->form_name, get_form_flag(r->flags), r->flags,
1838 r->size.width, r->size.height,
1839 r->area.left, r->area.right,
1840 r->area.top, r->area.bottom);
1843 /****************************************************************************
1844 ****************************************************************************/
1846 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1847 int argc, const char **argv)
1852 char *servername = NULL, *printername = NULL;
1853 bool got_handle = False;
1855 uint32_t offered = 0;
1856 union spoolss_FormInfo info;
1859 /* Parse the command arguments */
1862 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1866 /* Get a printer handle */
1868 if (asprintf(&servername, "\\\\%s", cli->desthost) == -1) {
1871 strupper_m(servername);
1872 if (asprintf(&printername, "%s\\%s", servername, argv[1]) == -1) {
1873 SAFE_FREE(servername);
1877 werror = rpccli_spoolss_open_printer_ex(
1878 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1879 servername, cli->auth->user_name, &handle);
1881 if (!W_ERROR_IS_OK(werror))
1888 status = rpccli_spoolss_GetForm(cli, mem_ctx,
1897 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
1898 buffer = data_blob_talloc(mem_ctx, NULL, needed);
1900 status = rpccli_spoolss_GetForm(cli, mem_ctx,
1911 if (!NT_STATUS_IS_OK(status)) {
1915 display_form_info1(&info.info1);
1918 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1920 SAFE_FREE(servername);
1921 SAFE_FREE(printername);
1926 /****************************************************************************
1927 ****************************************************************************/
1929 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
1930 TALLOC_CTX *mem_ctx, int argc,
1936 char *servername = NULL, *printername = NULL;
1937 bool got_handle = False;
1939 /* Parse the command arguments */
1942 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1946 /* Get a printer handle */
1948 if (asprintf(&servername, "\\\\%s", cli->desthost) == -1) {
1951 strupper_m(servername);
1952 if (asprintf(&printername, "%s\\%s", servername, argv[1]) == -1) {
1953 SAFE_FREE(servername);
1957 werror = rpccli_spoolss_open_printer_ex(
1958 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1959 servername, cli->auth->user_name, &handle);
1961 if (!W_ERROR_IS_OK(werror))
1966 /* Delete the form */
1968 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
1972 if (!NT_STATUS_IS_OK(status)) {
1973 return ntstatus_to_werror(status);
1978 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1980 SAFE_FREE(servername);
1981 SAFE_FREE(printername);
1986 /****************************************************************************
1987 ****************************************************************************/
1989 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
1990 TALLOC_CTX *mem_ctx, int argc,
1995 char *servername = NULL, *printername = NULL;
1996 bool got_handle = False;
1997 uint32 num_forms, level = 1, i;
2000 /* Parse the command arguments */
2003 printf ("Usage: %s <printer>\n", argv[0]);
2007 /* Get a printer handle */
2009 if (asprintf(&servername, "\\\\%s", cli->desthost) == -1) {
2012 strupper_m(servername);
2013 if (asprintf(&printername, "%s\\%s", servername, argv[1]) == -1) {
2014 SAFE_FREE(servername);
2018 werror = rpccli_spoolss_open_printer_ex(
2019 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2020 servername, cli->auth->user_name, &handle);
2022 if (!W_ERROR_IS_OK(werror))
2027 /* Enumerate forms */
2029 werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
2031 if (!W_ERROR_IS_OK(werror))
2034 /* Display output */
2036 for (i = 0; i < num_forms; i++) {
2038 display_form(&forms[i]);
2044 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2046 SAFE_FREE(servername);
2047 SAFE_FREE(printername);
2052 /****************************************************************************
2053 ****************************************************************************/
2055 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2056 TALLOC_CTX *mem_ctx,
2057 int argc, const char **argv)
2060 fstring servername, printername, user;
2062 bool opened_hnd = False;
2063 PRINTER_INFO_CTR ctr;
2064 PRINTER_INFO_0 info;
2065 REGISTRY_VALUE value;
2066 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2068 /* parse the command arguments */
2070 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2071 " <value> <data>\n",
2073 result = WERR_INVALID_PARAM;
2077 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2078 strupper_m(servername);
2079 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
2080 fstrcpy(user, cli->auth->user_name);
2082 value.type = REG_NONE;
2084 if (strequal(argv[2], "string")) {
2085 value.type = REG_SZ;
2088 if (strequal(argv[2], "binary")) {
2089 value.type = REG_BINARY;
2092 if (strequal(argv[2], "dword")) {
2093 value.type = REG_DWORD;
2096 if (strequal(argv[2], "multistring")) {
2097 value.type = REG_MULTI_SZ;
2100 if (value.type == REG_NONE) {
2101 printf("Unknown data type: %s\n", argv[2]);
2102 result = WERR_INVALID_PARAM;
2106 /* get a printer handle */
2107 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
2108 MAXIMUM_ALLOWED_ACCESS, servername,
2110 if (!W_ERROR_IS_OK(result))
2115 ctr.printers_0 = &info;
2117 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
2119 if (!W_ERROR_IS_OK(result))
2122 printf("%s\n", current_timestring(tmp_ctx, True));
2123 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
2125 /* Set the printer data */
2127 fstrcpy(value.valuename, argv[3]);
2129 switch (value.type) {
2132 init_unistr2(&data, argv[4], UNI_STR_TERMINATE);
2133 value.size = data.uni_str_len * 2;
2135 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer,
2138 value.data_p = NULL;
2143 uint32 data = strtoul(argv[4], NULL, 10);
2144 value.size = sizeof(data);
2146 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data,
2149 value.data_p = NULL;
2154 DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]);
2155 value.data_p = data.data;
2156 value.size = data.length;
2159 case REG_MULTI_SZ: {
2164 for (i=4; i<argc; i++) {
2165 if (strcmp(argv[i], "NULL") == 0) {
2168 len += strlen(argv[i])+1;
2172 value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size);
2173 if (value.data_p == NULL) {
2174 result = WERR_NOMEM;
2178 p = (char *)value.data_p;
2180 for (i=4; i<argc; i++) {
2181 size_t l = (strlen(argv[i])+1)*2;
2182 rpcstr_push(p, argv[i], len, STR_TERMINATE);
2186 SMB_ASSERT(len == 0);
2190 printf("Unknown data type: %s\n", argv[2]);
2191 result = WERR_INVALID_PARAM;
2195 result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
2197 if (!W_ERROR_IS_OK(result)) {
2198 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2201 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2203 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
2205 if (!W_ERROR_IS_OK(result))
2208 printf("%s\n", current_timestring(tmp_ctx, True));
2209 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
2213 TALLOC_FREE(tmp_ctx);
2215 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2220 /****************************************************************************
2221 ****************************************************************************/
2223 static void display_job_info_1(JOB_INFO_1 *job)
2225 fstring username = "", document = "", text_status = "";
2227 rpcstr_pull(username, job->username.buffer,
2228 sizeof(username), -1, STR_TERMINATE);
2230 rpcstr_pull(document, job->document.buffer,
2231 sizeof(document), -1, STR_TERMINATE);
2233 rpcstr_pull(text_status, job->text_status.buffer,
2234 sizeof(text_status), -1, STR_TERMINATE);
2236 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
2237 username, document, text_status, job->pagesprinted,
2241 /****************************************************************************
2242 ****************************************************************************/
2244 static void display_job_info_2(JOB_INFO_2 *job)
2246 fstring username = "", document = "", text_status = "";
2248 rpcstr_pull(username, job->username.buffer,
2249 sizeof(username), -1, STR_TERMINATE);
2251 rpcstr_pull(document, job->document.buffer,
2252 sizeof(document), -1, STR_TERMINATE);
2254 rpcstr_pull(text_status, job->text_status.buffer,
2255 sizeof(text_status), -1, STR_TERMINATE);
2257 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
2258 username, document, text_status, job->pagesprinted,
2259 job->totalpages, job->size);
2262 /****************************************************************************
2263 ****************************************************************************/
2265 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2266 TALLOC_CTX *mem_ctx, int argc,
2270 uint32 level = 1, num_jobs, i;
2271 bool got_hnd = False;
2272 char *printername = NULL;
2273 fstring servername, user;
2277 if (argc < 2 || argc > 3) {
2278 printf("Usage: %s printername [level]\n", argv[0]);
2283 level = atoi(argv[2]);
2285 /* Open printer handle */
2287 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2288 strupper_m(servername);
2289 fstrcpy(user, cli->auth->user_name);
2290 printername = talloc_asprintf(mem_ctx, "\\\\%s\\", cli->desthost);
2294 strupper_m(printername);
2295 printername = talloc_asprintf_append(printername, "%s", argv[1]);
2300 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2301 "", MAXIMUM_ALLOWED_ACCESS,
2302 servername, user, &hnd);
2304 if (!W_ERROR_IS_OK(result))
2309 /* Enumerate ports */
2311 result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
2314 if (!W_ERROR_IS_OK(result))
2317 for (i = 0; i < num_jobs; i++) {
2320 display_job_info_1(&ctr.job.job_info_1[i]);
2323 display_job_info_2(&ctr.job.job_info_2[i]);
2326 d_printf("unknown info level %d\n", level);
2333 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2338 /****************************************************************************
2339 ****************************************************************************/
2341 static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
2342 TALLOC_CTX *mem_ctx, int argc,
2346 uint32 i=0, val_needed, data_needed;
2347 bool got_hnd = False;
2348 char *printername = NULL;
2349 fstring servername, user;
2353 printf("Usage: %s printername\n", argv[0]);
2357 /* Open printer handle */
2359 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2360 strupper_m(servername);
2361 fstrcpy(user, cli->auth->user_name);
2362 printername = talloc_asprintf(mem_ctx, "\\\\%s\\", cli->desthost);
2366 strupper_m(printername);
2367 printername = talloc_asprintf_append(printername, "%s", argv[1]);
2372 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2373 "", MAXIMUM_ALLOWED_ACCESS,
2374 servername, user, &hnd);
2376 if (!W_ERROR_IS_OK(result))
2381 /* Enumerate data */
2383 result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2384 &val_needed, &data_needed,
2386 while (W_ERROR_IS_OK(result)) {
2387 REGISTRY_VALUE value;
2388 result = rpccli_spoolss_enumprinterdata(
2389 cli, mem_ctx, &hnd, i++, val_needed,
2390 data_needed, 0, 0, &value);
2391 if (W_ERROR_IS_OK(result))
2392 display_reg_value(value);
2394 if (W_ERROR_V(result) == ERRnomoreitems)
2395 result = W_ERROR(ERRsuccess);
2399 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2404 /****************************************************************************
2405 ****************************************************************************/
2407 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2408 TALLOC_CTX *mem_ctx, int argc,
2413 bool got_hnd = False;
2414 char *printername = NULL;
2415 fstring servername, user;
2416 const char *keyname = NULL;
2418 REGVAL_CTR *ctr = NULL;
2421 printf("Usage: %s printername <keyname>\n", argv[0]);
2427 /* Open printer handle */
2429 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2430 strupper_m(servername);
2431 fstrcpy(user, cli->auth->user_name);
2433 printername = talloc_asprintf(mem_ctx, "\\\\%s\\", cli->desthost);
2437 strupper_m(printername);
2438 printername = talloc_asprintf_append(printername, "%s", argv[1]);
2443 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2444 "", MAXIMUM_ALLOWED_ACCESS,
2445 servername, user, &hnd);
2447 if (!W_ERROR_IS_OK(result))
2452 /* Enumerate subkeys */
2454 if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
2457 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
2459 if (!W_ERROR_IS_OK(result))
2462 for (i=0; i < ctr->num_values; i++) {
2463 display_reg_value(*(ctr->values[i]));
2470 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2475 /****************************************************************************
2476 ****************************************************************************/
2478 static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
2479 TALLOC_CTX *mem_ctx, int argc,
2483 bool got_hnd = False;
2484 char *printername = NULL;
2485 fstring servername, user;
2486 const char *keyname = NULL;
2488 uint16 *keylist = NULL, *curkey;
2490 if (argc < 2 || argc > 3) {
2491 printf("Usage: %s printername [keyname]\n", argv[0]);
2500 /* Open printer handle */
2502 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2503 strupper_m(servername);
2504 fstrcpy(user, cli->auth->user_name);
2506 printername = talloc_asprintf(mem_ctx, "\\\\%s\\", cli->desthost);
2510 strupper_m(printername);
2511 printername = talloc_asprintf_append(printername, "%s", argv[1]);
2517 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2518 "", MAXIMUM_ALLOWED_ACCESS,
2519 servername, user, &hnd);
2521 if (!W_ERROR_IS_OK(result))
2526 /* Enumerate subkeys */
2528 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
2530 if (!W_ERROR_IS_OK(result))
2534 while (*curkey != 0) {
2535 char *subkey = NULL;
2536 rpcstr_pull_talloc(mem_ctx, &subkey, curkey, -1,
2541 printf("%s\n", subkey);
2542 curkey += strlen(subkey) + 1;
2550 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2555 /****************************************************************************
2556 ****************************************************************************/
2558 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2559 TALLOC_CTX *mem_ctx, int argc,
2562 fstring servername, printername;
2564 bool got_hnd = False;
2566 SPOOL_NOTIFY_OPTION option;
2569 printf("Usage: %s printername\n", argv[0]);
2576 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2577 strupper_m(servername);
2579 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s",
2580 cli->desthost, argv[1]);
2581 strupper_m(printername);
2583 result = rpccli_spoolss_open_printer_ex(
2584 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2585 servername, cli->auth->user_name, &hnd);
2587 if (!W_ERROR_IS_OK(result)) {
2588 printf("Error opening %s\n", argv[1]);
2594 /* Create spool options */
2596 ZERO_STRUCT(option);
2599 option.option_type_ptr = 1;
2600 option.count = option.ctr.count = 2;
2602 option.ctr.type = TALLOC_ARRAY(mem_ctx, SPOOL_NOTIFY_OPTION_TYPE, 2);
2603 if (option.ctr.type == NULL) {
2604 result = WERR_NOMEM;
2608 ZERO_STRUCT(option.ctr.type[0]);
2609 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2610 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2611 option.ctr.type[0].fields_ptr = 1;
2612 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2614 ZERO_STRUCT(option.ctr.type[1]);
2615 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2616 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2617 option.ctr.type[1].fields_ptr = 1;
2618 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2622 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2623 strupper_m(servername);
2625 result = rpccli_spoolss_rffpcnex(
2626 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2628 if (!W_ERROR_IS_OK(result)) {
2629 printf("Error rffpcnex %s\n", argv[1]);
2635 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2640 /****************************************************************************
2641 ****************************************************************************/
2643 static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2644 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2646 PRINTER_INFO_CTR ctr1, ctr2;
2648 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
2650 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
2651 werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1);
2652 if ( !W_ERROR_IS_OK(werror) ) {
2653 printf("failed (%s)\n", win_errstr(werror));
2654 talloc_destroy(mem_ctx);
2659 printf("Retrieving printer properties for %s...", cli2->desthost);
2660 werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2);
2661 if ( !W_ERROR_IS_OK(werror) ) {
2662 printf("failed (%s)\n", win_errstr(werror));
2663 talloc_destroy(mem_ctx);
2668 talloc_destroy(mem_ctx);
2673 /****************************************************************************
2674 ****************************************************************************/
2676 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2677 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2679 PRINTER_INFO_CTR ctr1, ctr2;
2681 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
2682 SEC_DESC *sd1, *sd2;
2686 printf("Retrieving printer security for %s...", cli1->desthost);
2687 werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1);
2688 if ( !W_ERROR_IS_OK(werror) ) {
2689 printf("failed (%s)\n", win_errstr(werror));
2695 printf("Retrieving printer security for %s...", cli2->desthost);
2696 werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2);
2697 if ( !W_ERROR_IS_OK(werror) ) {
2698 printf("failed (%s)\n", win_errstr(werror));
2707 if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) {
2708 printf("NULL PRINTER_INFO_3!\n");
2713 sd1 = ctr1.printers_3->secdesc;
2714 sd2 = ctr2.printers_3->secdesc;
2716 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
2717 printf("NULL secdesc!\n");
2722 if (!sec_desc_equal( sd1, sd2 ) ) {
2723 printf("Security Descriptors *not* equal!\n");
2728 printf("Security descriptors match\n");
2731 talloc_destroy(mem_ctx);
2736 /****************************************************************************
2737 ****************************************************************************/
2739 extern struct user_auth_info *rpcclient_auth_info;
2741 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
2742 TALLOC_CTX *mem_ctx, int argc,
2745 fstring printername, servername1, servername2;
2746 char *printername_path = NULL;
2747 struct cli_state *cli_server1 = rpc_pipe_np_smb_conn(cli);
2748 struct cli_state *cli_server2 = NULL;
2749 struct rpc_pipe_client *cli2 = NULL;
2750 POLICY_HND hPrinter1, hPrinter2;
2755 printf("Usage: %s <printer> <server>\n", argv[0]);
2759 fstrcpy( printername, argv[1] );
2761 fstrcpy( servername1, cli->desthost );
2762 fstrcpy( servername2, argv[2] );
2763 strupper_m( servername1 );
2764 strupper_m( servername2 );
2766 /* first get the connection to the remote server */
2768 nt_status = cli_full_connection(&cli_server2, global_myname(), servername2,
2771 get_cmdline_auth_info_username(rpcclient_auth_info),
2773 get_cmdline_auth_info_password(rpcclient_auth_info),
2774 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
2775 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
2777 if ( !NT_STATUS_IS_OK(nt_status) )
2778 return WERR_GENERAL_FAILURE;
2780 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &syntax_spoolss,
2782 if (!NT_STATUS_IS_OK(nt_status)) {
2783 printf("failed to open spoolss pipe on server %s (%s)\n",
2784 servername2, nt_errstr(nt_status));
2785 return WERR_GENERAL_FAILURE;
2788 /* now open up both printers */
2790 printername_path = talloc_asprintf(mem_ctx,
2794 if (!printername_path) {
2797 printf("Opening %s...", printername_path);
2798 werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, printername_path,
2799 "", PRINTER_ALL_ACCESS, servername1, cli_server1->user_name, &hPrinter1);
2800 if ( !W_ERROR_IS_OK(werror) ) {
2801 printf("failed (%s)\n", win_errstr(werror));
2806 printername_path = talloc_asprintf(mem_ctx,
2810 if (!printername_path) {
2813 printf("Opening %s...", printername_path);
2814 werror = rpccli_spoolss_open_printer_ex( cli2, mem_ctx, printername_path,
2815 "", PRINTER_ALL_ACCESS, servername2, cli_server2->user_name, &hPrinter2 );
2816 if ( !W_ERROR_IS_OK(werror) ) {
2817 printf("failed (%s)\n", win_errstr(werror));
2822 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
2823 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
2825 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
2832 printf("Closing printers...");
2833 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
2834 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
2837 /* close the second remote connection */
2839 cli_shutdown( cli_server2 );
2843 /* List of commands exported by this module */
2844 struct cmd_set spoolss_commands[] = {
2848 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &syntax_spoolss, NULL, "Add a print driver", "" },
2849 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &syntax_spoolss, NULL, "Add a printer", "" },
2850 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &syntax_spoolss, NULL, "Delete a printer driver", "" },
2851 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &syntax_spoolss, NULL, "Delete a printer driver with files", "" },
2852 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &syntax_spoolss, NULL, "Enumerate printer data", "" },
2853 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" },
2854 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" },
2855 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" },
2856 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" },
2857 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" },
2858 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" },
2859 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &syntax_spoolss, NULL, "Get print driver data", "" },
2860 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &syntax_spoolss, NULL, "Get printer driver data with keyname", ""},
2861 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &syntax_spoolss, NULL, "Get print driver information", "" },
2862 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &syntax_spoolss, NULL, "Get print driver upload directory", "" },
2863 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &syntax_spoolss, NULL, "Get printer info", "" },
2864 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &syntax_spoolss, NULL, "Open printer handle", "" },
2865 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &syntax_spoolss, NULL, "Set printer driver", "" },
2866 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &syntax_spoolss, NULL, "Get print processor directory", "" },
2867 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &syntax_spoolss, NULL, "Add form", "" },
2868 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &syntax_spoolss, NULL, "Set form", "" },
2869 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &syntax_spoolss, NULL, "Get form", "" },
2870 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &syntax_spoolss, NULL, "Delete form", "" },
2871 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &syntax_spoolss, NULL, "Enumerate forms", "" },
2872 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &syntax_spoolss, NULL, "Set printer comment", "" },
2873 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &syntax_spoolss, NULL, "Set printername", "" },
2874 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &syntax_spoolss, NULL, "Set REG_SZ printer data", "" },
2875 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &syntax_spoolss, NULL, "Rffpcnex test", "" },
2876 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &syntax_spoolss, NULL, "Printer comparison test", "" },