2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001
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 2 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, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "rpcclient.h"
29 const char *long_archi;
30 const char *short_archi;
34 static const struct table_node archi_table[]= {
36 {"Windows 4.0", "WIN40", 0 },
37 {"Windows NT x86", "W32X86", 2 },
38 {"Windows NT x86", "W32X86", 3 },
39 {"Windows NT R4000", "W32MIPS", 2 },
40 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
41 {"Windows NT PowerPC", "W32PPC", 2 },
42 {"Windows IA64", "IA64", 3 },
49 * rpcclient module for SPOOLSS rpc pipe.
51 * This generally just parses and checks command lines, and then calls
52 * a cli_spoolss function.
55 /****************************************************************************
56 function to do the mapping between the long architecture name and
58 ****************************************************************************/
59 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
63 DEBUG(107,("Getting architecture dependant directory\n"));
66 } while ( (archi_table[i].long_archi!=NULL ) &&
67 StrCaseCmp(long_archi, archi_table[i].long_archi) );
69 if (archi_table[i].long_archi==NULL) {
70 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
74 /* this might be client code - but shouldn't this be an fstrcpy etc? */
77 DEBUGADD(108,("index: [%d]\n", i));
78 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
79 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
81 return archi_table[i].short_archi;
85 /**********************************************************************
86 * dummy function -- placeholder
88 static WERROR cmd_spoolss_not_implemented(struct cli_state *cli,
90 int argc, const char **argv)
92 printf ("(*) This command is not currently implemented.\n");
97 /***********************************************************************
98 * Get printer information
100 static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
102 int argc, const char **argv)
106 fstring servername, user;
110 printf("Usage: %s <printername>\n", argv[0]);
115 return WERR_GENERAL_FAILURE;
117 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
118 strupper_m(servername);
119 fstrcpy(user, cli->user_name);
120 fstrcpy(printername, argv[1]);
122 /* Open the printer handle */
124 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
125 "", PRINTER_ALL_ACCESS,
126 servername, user, &hnd);
128 if (W_ERROR_IS_OK(werror)) {
129 printf("Printer %s opened successfully\n", printername);
130 werror = cli_spoolss_close_printer(cli, mem_ctx, &hnd);
132 if (!W_ERROR_IS_OK(werror)) {
133 printf("Error closing printer handle! (%s)\n",
134 get_dos_error_msg(werror));
142 /****************************************************************************
143 printer info level 0 display function
144 ****************************************************************************/
145 static void display_print_info_0(PRINTER_INFO_0 *i0)
148 fstring servername = "";
153 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
155 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
157 printf("\tprintername:[%s]\n", name);
158 printf("\tservername:[%s]\n", servername);
159 printf("\tcjobs:[0x%x]\n", i0->cjobs);
160 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
162 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
163 i0->day, i0->dayofweek);
164 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
165 i0->second, i0->milliseconds);
167 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
168 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
170 printf("\tmajorversion:[0x%x]\n", i0->major_version);
171 printf("\tbuildversion:[0x%x]\n", i0->build_version);
173 printf("\tunknown7:[0x%x]\n", i0->unknown7);
174 printf("\tunknown8:[0x%x]\n", i0->unknown8);
175 printf("\tunknown9:[0x%x]\n", i0->unknown9);
176 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
177 printf("\tunknown11:[0x%x]\n", i0->unknown11);
178 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
179 printf("\tunknown13:[0x%x]\n", i0->unknown13);
180 printf("\tunknown14:[0x%x]\n", i0->unknown14);
181 printf("\tunknown15:[0x%x]\n", i0->unknown15);
182 printf("\tunknown16:[0x%x]\n", i0->unknown16);
183 printf("\tchange_id:[0x%x]\n", i0->change_id);
184 printf("\tunknown18:[0x%x]\n", i0->unknown18);
185 printf("\tstatus:[0x%x]\n", i0->status);
186 printf("\tunknown20:[0x%x]\n", i0->unknown20);
187 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
188 printf("\tunknown22:[0x%x]\n", i0->unknown22);
189 printf("\tunknown23:[0x%x]\n", i0->unknown23);
190 printf("\tunknown24:[0x%x]\n", i0->unknown24);
191 printf("\tunknown25:[0x%x]\n", i0->unknown25);
192 printf("\tunknown26:[0x%x]\n", i0->unknown26);
193 printf("\tunknown27:[0x%x]\n", i0->unknown27);
194 printf("\tunknown28:[0x%x]\n", i0->unknown28);
195 printf("\tunknown29:[0x%x]\n", i0->unknown29);
200 /****************************************************************************
201 printer info level 1 display function
202 ****************************************************************************/
203 static void display_print_info_1(PRINTER_INFO_1 *i1)
209 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
212 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
213 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
215 printf("\tflags:[0x%x]\n", i1->flags);
216 printf("\tname:[%s]\n", name);
217 printf("\tdescription:[%s]\n", desc);
218 printf("\tcomment:[%s]\n", comm);
223 /****************************************************************************
224 printer info level 2 display function
225 ****************************************************************************/
226 static void display_print_info_2(PRINTER_INFO_2 *i2)
228 fstring servername = "";
229 fstring printername = "";
230 fstring sharename = "";
231 fstring portname = "";
232 fstring drivername = "";
233 fstring comment = "";
234 fstring location = "";
235 fstring sepfile = "";
236 fstring printprocessor = "";
237 fstring datatype = "";
238 fstring parameters = "";
240 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
242 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
244 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
246 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
248 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
250 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
252 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
254 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
256 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
258 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
260 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
262 printf("\tservername:[%s]\n", servername);
263 printf("\tprintername:[%s]\n", printername);
264 printf("\tsharename:[%s]\n", sharename);
265 printf("\tportname:[%s]\n", portname);
266 printf("\tdrivername:[%s]\n", drivername);
267 printf("\tcomment:[%s]\n", comment);
268 printf("\tlocation:[%s]\n", location);
269 printf("\tsepfile:[%s]\n", sepfile);
270 printf("\tprintprocessor:[%s]\n", printprocessor);
271 printf("\tdatatype:[%s]\n", datatype);
272 printf("\tparameters:[%s]\n", parameters);
273 printf("\tattributes:[0x%x]\n", i2->attributes);
274 printf("\tpriority:[0x%x]\n", i2->priority);
275 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
276 printf("\tstarttime:[0x%x]\n", i2->starttime);
277 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
278 printf("\tstatus:[0x%x]\n", i2->status);
279 printf("\tcjobs:[0x%x]\n", i2->cjobs);
280 printf("\taverageppm:[0x%x]\n", i2->averageppm);
283 display_sec_desc(i2->secdesc);
288 /****************************************************************************
289 printer info level 3 display function
290 ****************************************************************************/
291 static void display_print_info_3(PRINTER_INFO_3 *i3)
293 printf("\tflags:[0x%x]\n", i3->flags);
295 display_sec_desc(i3->secdesc);
300 /* Enumerate printers */
302 static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
304 int argc, const char **argv)
307 uint32 info_level = 1;
308 PRINTER_INFO_CTR ctr;
309 uint32 i = 0, num_printers, needed;
314 printf("Usage: %s [level] [name]\n", argv[0]);
319 info_level = atoi(argv[1]);
322 fstrcpy(name, argv[2]);
324 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
328 /* Enumerate printers -- Should we enumerate types other
329 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
333 result = cli_spoolss_enum_printers(
334 cli, mem_ctx, 0, &needed, name, PRINTER_ENUM_LOCAL,
335 info_level, &num_printers, &ctr);
337 if (W_ERROR_V(result) == ERRinsufficientbuffer)
338 result = cli_spoolss_enum_printers(
339 cli, mem_ctx, needed, NULL, name, PRINTER_ENUM_LOCAL,
340 info_level, &num_printers, &ctr);
342 if (W_ERROR_IS_OK(result)) {
345 printf ("No printers returned.\n");
349 for (i = 0; i < num_printers; i++) {
352 display_print_info_0(&ctr.printers_0[i]);
355 display_print_info_1(&ctr.printers_1[i]);
358 display_print_info_2(&ctr.printers_2[i]);
361 display_print_info_3(&ctr.printers_3[i]);
364 printf("unknown info level %d\n", info_level);
374 /****************************************************************************
375 port info level 1 display function
376 ****************************************************************************/
377 static void display_port_info_1(PORT_INFO_1 *i1)
381 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
382 printf("\tPort Name:\t[%s]\n", buffer);
385 /****************************************************************************
386 port info level 2 display function
387 ****************************************************************************/
388 static void display_port_info_2(PORT_INFO_2 *i2)
392 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
393 printf("\tPort Name:\t[%s]\n", buffer);
394 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
396 printf("\tMonitor Name:\t[%s]\n", buffer);
397 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
399 printf("\tDescription:\t[%s]\n", buffer);
400 printf("\tPort Type:\t" );
401 if ( i2->port_type ) {
402 int comma = 0; /* hack */
404 if ( i2->port_type & PORT_TYPE_READ ) {
408 if ( i2->port_type & PORT_TYPE_WRITE ) {
409 printf( "%sWrite", comma ? ", " : "" );
412 /* These two have slightly different interpretations
413 on 95/98/ME but I'm disregarding that for now */
414 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
415 printf( "%sRedirected", comma ? ", " : "" );
418 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
419 printf( "%sNet-Attached", comma ? ", " : "" );
423 printf( "[Unset]\n" );
425 printf("\tReserved:\t[%d]\n", i2->reserved);
429 /* Enumerate ports */
431 static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
432 TALLOC_CTX *mem_ctx, int argc,
436 uint32 needed, info_level = 1;
441 printf("Usage: %s [level]\n", argv[0]);
446 info_level = atoi(argv[1]);
448 /* Enumerate ports */
452 result = cli_spoolss_enum_ports(cli, mem_ctx, 0, &needed, info_level,
455 if (W_ERROR_V(result) == ERRinsufficientbuffer)
456 result = cli_spoolss_enum_ports(cli, mem_ctx, needed, NULL,
457 info_level, &returned, &ctr);
459 if (W_ERROR_IS_OK(result)) {
462 for (i = 0; i < returned; i++) {
463 switch (info_level) {
465 display_port_info_1(&ctr.port.info_1[i]);
468 display_port_info_2(&ctr.port.info_2[i]);
471 printf("unknown info level %d\n", info_level);
480 /***********************************************************************
481 * Set printer comment - use a level2 set.
483 static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
485 int argc, const char **argv)
490 uint32 info_level = 2;
491 BOOL opened_hnd = False;
492 PRINTER_INFO_CTR ctr;
498 if (argc == 1 || argc > 3) {
499 printf("Usage: %s printername comment\n", argv[0]);
504 /* Open a printer handle */
506 fstrcpy(comment, argv[2]);
509 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
510 strupper_m(servername);
511 fstrcpy(printername, argv[1]);
512 fstrcpy(user, cli->user_name);
514 /* get a printer handle */
515 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
516 PRINTER_ALL_ACCESS, servername,
519 if (!W_ERROR_IS_OK(result))
524 /* Get printer info */
525 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, info_level, &ctr);
527 if (W_ERROR_V(result) == ERRinsufficientbuffer)
528 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
530 if (!W_ERROR_IS_OK(result))
534 /* Modify the comment. */
535 init_unistr(&ctr.printers_2->comment, comment);
536 ctr.printers_2->devmode = NULL;
537 ctr.printers_2->secdesc = NULL;
539 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
540 if (W_ERROR_IS_OK(result))
541 printf("Success in setting comment.\n");
545 cli_spoolss_close_printer(cli, mem_ctx, &pol);
550 /***********************************************************************
551 * Set printer name - use a level2 set.
553 static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
555 int argc, const char **argv)
560 uint32 info_level = 2;
561 BOOL opened_hnd = False;
562 PRINTER_INFO_CTR ctr;
568 if (argc == 1 || argc > 3) {
569 printf("Usage: %s printername new_printername\n", argv[0]);
574 /* Open a printer handle */
576 fstrcpy(new_printername, argv[2]);
579 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
580 strupper_m(servername);
581 fstrcpy(printername, argv[1]);
582 fstrcpy(user, cli->user_name);
584 /* get a printer handle */
585 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
586 PRINTER_ALL_ACCESS, servername,
589 if (!W_ERROR_IS_OK(result))
594 /* Get printer info */
595 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, info_level, &ctr);
597 if (W_ERROR_V(result) == ERRinsufficientbuffer)
598 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
600 if (!W_ERROR_IS_OK(result))
604 /* Modify the printername. */
605 init_unistr(&ctr.printers_2->printername, new_printername);
606 ctr.printers_2->devmode = NULL;
607 ctr.printers_2->secdesc = NULL;
609 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
610 if (W_ERROR_IS_OK(result))
611 printf("Success in setting printername.\n");
615 cli_spoolss_close_printer(cli, mem_ctx, &pol);
620 /***********************************************************************
621 * Get printer information
623 static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
625 int argc, const char **argv)
629 uint32 info_level = 1;
630 BOOL opened_hnd = False;
631 PRINTER_INFO_CTR ctr;
637 if (argc == 1 || argc > 3) {
638 printf("Usage: %s <printername> [level]\n", argv[0]);
642 /* Open a printer handle */
644 info_level = atoi(argv[2]);
647 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
648 strupper_m(servername);
649 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
650 fstrcpy(user, cli->user_name);
652 /* get a printer handle */
654 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
655 "", MAXIMUM_ALLOWED_ACCESS,
656 servername, user, &pol);
658 if (!W_ERROR_IS_OK(result))
663 /* Get printer info */
665 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
666 &pol, info_level, &ctr);
668 if (W_ERROR_V(result) == ERRinsufficientbuffer)
669 result = cli_spoolss_getprinter(
670 cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
672 if (!W_ERROR_IS_OK(result))
675 /* Display printer info */
677 switch (info_level) {
679 display_print_info_0(ctr.printers_0);
682 display_print_info_1(ctr.printers_1);
685 display_print_info_2(ctr.printers_2);
688 display_print_info_3(ctr.printers_3);
691 printf("unknown info level %d\n", info_level);
697 cli_spoolss_close_printer(cli, mem_ctx, &pol);
702 static void display_reg_value(REGISTRY_VALUE value)
708 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
709 *((uint32 *) value.data_p));
712 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
714 printf("%s: REG_SZ: %s\n", value.valuename, text);
717 printf("%s: REG_BINARY: unknown length value not displayed\n",
721 uint16 *curstr = (uint16 *) value.data_p;
722 uint8 *start = value.data_p;
723 printf("%s: REG_MULTI_SZ:\n", value.valuename);
724 while ((*curstr != 0) &&
725 ((uint8 *) curstr < start + value.size)) {
726 rpcstr_pull(text, curstr, sizeof(text), -1,
728 printf(" %s\n", text);
729 curstr += strlen(text) + 1;
734 printf("%s: unknown type %d\n", value.valuename, value.type);
739 /***********************************************************************
742 static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
744 int argc, const char **argv)
748 BOOL opened_hnd = False;
753 const char *valuename;
754 REGISTRY_VALUE value;
757 printf("Usage: %s <printername> <valuename>\n", argv[0]);
758 printf("<printername> of . queries print server\n");
763 /* Open a printer handle */
765 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
766 strupper_m(servername);
767 if (strncmp(argv[1], ".", sizeof(".")) == 0)
768 fstrcpy(printername, servername);
770 slprintf(printername, sizeof(servername)-1, "%s\\%s",
771 servername, argv[1]);
772 fstrcpy(user, cli->user_name);
774 /* get a printer handle */
776 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
777 "", MAXIMUM_ALLOWED_ACCESS,
778 servername, user, &pol);
780 if (!W_ERROR_IS_OK(result))
785 /* Get printer info */
787 result = cli_spoolss_getprinterdata(cli, mem_ctx, 0, &needed,
788 &pol, valuename, &value);
790 if (W_ERROR_V(result) == ERRmoredata)
791 result = cli_spoolss_getprinterdata(
792 cli, mem_ctx, needed, NULL, &pol, valuename, &value);
794 if (!W_ERROR_IS_OK(result))
797 /* Display printer data */
799 fstrcpy(value.valuename, valuename);
800 display_reg_value(value);
805 cli_spoolss_close_printer(cli, mem_ctx, &pol);
810 /***********************************************************************
813 static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
815 int argc, const char **argv)
819 BOOL opened_hnd = False;
824 const char *valuename, *keyname;
825 REGISTRY_VALUE value;
828 printf("Usage: %s <printername> <keyname> <valuename>\n",
830 printf("<printername> of . queries print server\n");
836 /* Open a printer handle */
838 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
839 strupper_m(servername);
840 if (strncmp(argv[1], ".", sizeof(".")) == 0)
841 fstrcpy(printername, servername);
843 slprintf(printername, sizeof(printername)-1, "%s\\%s",
844 servername, argv[1]);
845 fstrcpy(user, cli->user_name);
847 /* get a printer handle */
849 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
850 "", MAXIMUM_ALLOWED_ACCESS,
851 servername, user, &pol);
853 if (!W_ERROR_IS_OK(result))
858 /* Get printer info */
860 result = cli_spoolss_getprinterdataex(cli, mem_ctx, 0, &needed,
861 &pol, keyname, valuename,
864 if (W_ERROR_V(result) == ERRmoredata)
865 result = cli_spoolss_getprinterdataex(cli, mem_ctx, needed,
869 if (!W_ERROR_IS_OK(result))
872 /* Display printer data */
874 fstrcpy(value.valuename, valuename);
875 display_reg_value(value);
880 cli_spoolss_close_printer(cli, mem_ctx, &pol);
885 /****************************************************************************
886 printer info level 0 display function
887 ****************************************************************************/
888 static void display_print_driver_1(DRIVER_INFO_1 *i1)
894 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
896 printf ("Printer Driver Info 1:\n");
897 printf ("\tDriver Name: [%s]\n\n", name);
902 /****************************************************************************
903 printer info level 1 display function
904 ****************************************************************************/
905 static void display_print_driver_2(DRIVER_INFO_2 *i1)
908 fstring architecture;
915 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
916 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
917 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
918 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
919 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
921 printf ("Printer Driver Info 2:\n");
922 printf ("\tVersion: [%x]\n", i1->version);
923 printf ("\tDriver Name: [%s]\n", name);
924 printf ("\tArchitecture: [%s]\n", architecture);
925 printf ("\tDriver Path: [%s]\n", driverpath);
926 printf ("\tDatafile: [%s]\n", datafile);
927 printf ("\tConfigfile: [%s]\n\n", configfile);
932 /****************************************************************************
933 printer info level 2 display function
934 ****************************************************************************/
935 static void display_print_driver_3(DRIVER_INFO_3 *i1)
938 fstring architecture = "";
939 fstring driverpath = "";
940 fstring datafile = "";
941 fstring configfile = "";
942 fstring helpfile = "";
943 fstring dependentfiles = "";
944 fstring monitorname = "";
945 fstring defaultdatatype = "";
953 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
954 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
955 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
956 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
957 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
958 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
959 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
960 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
962 printf ("Printer Driver Info 3:\n");
963 printf ("\tVersion: [%x]\n", i1->version);
964 printf ("\tDriver Name: [%s]\n",name);
965 printf ("\tArchitecture: [%s]\n", architecture);
966 printf ("\tDriver Path: [%s]\n", driverpath);
967 printf ("\tDatafile: [%s]\n", datafile);
968 printf ("\tConfigfile: [%s]\n", configfile);
969 printf ("\tHelpfile: [%s]\n\n", helpfile);
973 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
975 length+=strlen(dependentfiles)+1;
977 if (strlen(dependentfiles) > 0)
979 printf ("\tDependentfiles: [%s]\n", dependentfiles);
989 printf ("\tMonitorname: [%s]\n", monitorname);
990 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
995 /***********************************************************************
996 * Get printer information
998 static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
1000 int argc, const char **argv)
1004 uint32 info_level = 3;
1005 BOOL opened_hnd = False;
1006 PRINTER_DRIVER_CTR ctr;
1007 fstring printername,
1011 BOOL success = False;
1013 if ((argc == 1) || (argc > 3))
1015 printf("Usage: %s <printername> [level]\n", argv[0]);
1019 /* get the arguments need to open the printer handle */
1020 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1021 strupper_m(servername);
1022 fstrcpy(user, cli->user_name);
1023 fstrcpy(printername, argv[1]);
1025 info_level = atoi(argv[2]);
1027 /* Open a printer handle */
1029 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1031 servername, user, &pol);
1033 if (!W_ERROR_IS_OK(werror)) {
1034 printf("Error opening printer handle for %s!\n", printername);
1040 /* loop through and print driver info level for each architecture */
1042 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1045 werror = cli_spoolss_getprinterdriver(
1046 cli, mem_ctx, 0, &needed, &pol, info_level,
1047 archi_table[i].long_archi, archi_table[i].version,
1050 if (W_ERROR_V(werror) == ERRinsufficientbuffer) {
1051 werror = cli_spoolss_getprinterdriver(
1052 cli, mem_ctx, needed, NULL, &pol, info_level,
1053 archi_table[i].long_archi, archi_table[i].version,
1057 if (!W_ERROR_IS_OK(werror))
1060 /* need at least one success */
1064 printf ("\n[%s]\n", archi_table[i].long_archi);
1066 switch (info_level) {
1068 display_print_driver_1 (ctr.info1);
1071 display_print_driver_2 (ctr.info2);
1074 display_print_driver_3 (ctr.info3);
1077 printf("unknown info level %d\n", info_level);
1085 cli_spoolss_close_printer (cli, mem_ctx, &pol);
1093 /***********************************************************************
1094 * Get printer information
1096 static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
1097 TALLOC_CTX *mem_ctx,
1098 int argc, const char **argv)
1101 uint32 info_level = 1;
1102 PRINTER_DRIVER_CTR ctr;
1108 printf("Usage: enumdrivers [level]\n");
1113 info_level = atoi(argv[1]);
1116 /* loop through and print driver info level for each architecture */
1117 for (i=0; archi_table[i].long_archi!=NULL; i++)
1121 werror = cli_spoolss_enumprinterdrivers(
1122 cli, mem_ctx, 0, &needed, info_level,
1123 archi_table[i].long_archi, &returned, &ctr);
1125 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1126 werror = cli_spoolss_enumprinterdrivers(
1127 cli, mem_ctx, needed, NULL, info_level,
1128 archi_table[i].long_archi, &returned, &ctr);
1130 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1131 printf ("Server does not support environment [%s]\n",
1132 archi_table[i].long_archi);
1140 if (!W_ERROR_IS_OK(werror)) {
1141 printf ("Error getting driver for environment [%s] - %d\n",
1142 archi_table[i].long_archi, W_ERROR_V(werror));
1146 printf ("\n[%s]\n", archi_table[i].long_archi);
1151 for (j=0; j < returned; j++) {
1152 display_print_driver_1 (&(ctr.info1[j]));
1156 for (j=0; j < returned; j++) {
1157 display_print_driver_2 (&(ctr.info2[j]));
1161 for (j=0; j < returned; j++) {
1162 display_print_driver_3 (&(ctr.info3[j]));
1166 printf("unknown info level %d\n", info_level);
1174 /****************************************************************************
1175 printer info level 1 display function
1176 ****************************************************************************/
1177 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1183 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1185 printf ("\tDirectory Name:[%s]\n", name);
1188 /***********************************************************************
1189 * Get printer driver directory information
1191 static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
1192 TALLOC_CTX *mem_ctx,
1193 int argc, const char **argv)
1197 DRIVER_DIRECTORY_CTR ctr;
1201 printf("Usage: %s [environment]\n", argv[0]);
1205 /* Get the arguments need to open the printer handle */
1208 fstrcpy (env, argv[1]);
1210 fstrcpy (env, "Windows NT x86");
1212 /* Get the directory. Only use Info level 1 */
1214 result = cli_spoolss_getprinterdriverdir(
1215 cli, mem_ctx, 0, &needed, 1, env, &ctr);
1217 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1218 result = cli_spoolss_getprinterdriverdir(
1219 cli, mem_ctx, needed, NULL, 1, env, &ctr);
1221 if (W_ERROR_IS_OK(result))
1222 display_printdriverdir_1(ctr.info1);
1227 /*******************************************************************************
1228 set the version and environment fields of a DRIVER_INFO_3 struct
1229 ******************************************************************************/
1230 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1235 for (i=0; archi_table[i].long_archi != NULL; i++)
1237 if (strcmp(arch, archi_table[i].short_archi) == 0)
1239 info->version = archi_table[i].version;
1240 init_unistr (&info->architecture, archi_table[i].long_archi);
1245 if (archi_table[i].long_archi == NULL)
1247 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1254 /**************************************************************************
1255 wrapper for strtok to get the next parameter from a delimited list.
1256 Needed to handle the empty parameter string denoted by "NULL"
1257 *************************************************************************/
1258 static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
1262 /* get the next token */
1263 ptr = strtok(str, delim);
1265 /* a string of 'NULL' is used to represent an empty
1266 parameter because two consecutive delimiters
1267 will not return an empty string. See man strtok(3)
1269 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
1273 init_unistr(dest, ptr);
1278 /********************************************************************************
1279 fill in the members of a DRIVER_INFO_3 struct using a character
1280 string in the form of
1281 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1282 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1283 <Default Data Type>:<Comma Separated list of Files>
1284 *******************************************************************************/
1285 static BOOL init_drv_info_3_members (
1286 TALLOC_CTX *mem_ctx,
1287 DRIVER_INFO_3 *info,
1294 /* fill in the UNISTR fields */
1295 str = get_driver_3_param (args, ":", &info->name);
1296 str = get_driver_3_param (NULL, ":", &info->driverpath);
1297 str = get_driver_3_param (NULL, ":", &info->datafile);
1298 str = get_driver_3_param (NULL, ":", &info->configfile);
1299 str = get_driver_3_param (NULL, ":", &info->helpfile);
1300 str = get_driver_3_param (NULL, ":", &info->monitorname);
1301 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1303 /* <Comma Separated List of Dependent Files> */
1304 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1307 /* begin to strip out each filename */
1308 str = strtok(str, ",");
1312 /* keep a cumlative count of the str lengths */
1313 len += strlen(str)+1;
1314 str = strtok(NULL, ",");
1317 /* allocate the space; add one extra slot for a terminating NULL.
1318 Each filename is NULL terminated and the end contains a double
1320 if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL)
1322 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1325 for (i=0; i<len; i++)
1327 SSVAL(&info->dependentfiles[i], 0, str2[i]);
1329 info->dependentfiles[len] = '\0';
1335 static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
1336 TALLOC_CTX *mem_ctx,
1337 int argc, const char **argv)
1341 PRINTER_DRIVER_CTR ctr;
1342 DRIVER_INFO_3 info3;
1344 fstring driver_name;
1346 /* parse the command arguements */
1347 if (argc != 3 && argc != 4)
1349 printf ("Usage: %s <Environment> \\\n", argv[0]);
1350 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1351 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1352 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1353 printf ("\t[version]\n");
1358 /* Fill in the DRIVER_INFO_3 struct */
1360 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
1362 printf ("Error Unknown architechture [%s]\n", argv[1]);
1363 return WERR_INVALID_PARAM;
1366 set_drv_info_3_env(&info3, arch);
1368 if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
1370 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1371 return WERR_INVALID_PARAM;
1374 /* if printer driver version specified, override the default version
1375 * used by the architecture. This allows installation of Windows
1376 * 2000 (version 3) printer drivers. */
1379 info3.version = atoi(argv[3]);
1384 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1386 if (W_ERROR_IS_OK(result)) {
1387 rpcstr_pull(driver_name, info3.name.buffer,
1388 sizeof(driver_name), -1, STR_TERMINATE);
1389 printf ("Printer Driver %s successfully installed.\n",
1397 static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
1398 TALLOC_CTX *mem_ctx,
1399 int argc, const char **argv)
1403 PRINTER_INFO_CTR ctr;
1404 PRINTER_INFO_2 info2;
1407 /* parse the command arguements */
1410 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1414 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1415 strupper_m(servername);
1417 /* Fill in the DRIVER_INFO_2 struct */
1420 init_unistr( &info2.servername, servername);
1422 init_unistr( &info2.printername, argv[1]);
1423 init_unistr( &info2.sharename, argv[2]);
1424 init_unistr( &info2.drivername, argv[3]);
1425 init_unistr( &info2.portname, argv[4]);
1426 init_unistr( &info2.comment, "Created by rpcclient");
1427 init_unistr( &info2.printprocessor, "winprint");
1428 init_unistr( &info2.datatype, "RAW");
1429 info2.devmode = NULL;
1430 info2.secdesc = NULL;
1431 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1433 info2.defaultpriority = 0;
1434 info2.starttime = 0;
1435 info2.untiltime = 0;
1437 /* These three fields must not be used by AddPrinter()
1438 as defined in the MS Platform SDK documentation..
1442 info2.averageppm = 0;
1445 ctr.printers_2 = &info2;
1446 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1448 if (W_ERROR_IS_OK(result))
1449 printf ("Printer %s successfully installed.\n", argv[1]);
1454 static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
1455 TALLOC_CTX *mem_ctx,
1456 int argc, const char **argv)
1461 BOOL opened_hnd = False;
1462 PRINTER_INFO_CTR ctr;
1463 PRINTER_INFO_2 info2;
1469 /* parse the command arguements */
1472 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1476 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1477 strupper_m(servername);
1478 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1479 fstrcpy(user, cli->user_name);
1481 /* Get a printer handle */
1483 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1485 servername, user, &pol);
1487 if (!W_ERROR_IS_OK(result))
1492 /* Get printer info */
1494 ZERO_STRUCT (info2);
1495 ctr.printers_2 = &info2;
1497 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1500 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1501 result = cli_spoolss_getprinter(
1502 cli, mem_ctx, needed, NULL, &pol, level, &ctr);
1504 if (!W_ERROR_IS_OK(result)) {
1505 printf ("Unable to retrieve printer information!\n");
1509 /* Set the printer driver */
1511 init_unistr(&ctr.printers_2->drivername, argv[2]);
1513 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1515 if (!W_ERROR_IS_OK(result)) {
1516 printf("SetPrinter call failed!\n");
1520 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1526 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1532 static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
1533 TALLOC_CTX *mem_ctx,
1534 int argc, const char **argv)
1540 /* parse the command arguements */
1543 printf ("Usage: %s <driver>\n", argv[0]);
1547 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1548 strupper_m(servername);
1550 /* delete the driver for all architectures */
1551 for (i=0; archi_table[i].long_archi; i++)
1553 /* make the call to remove the driver */
1554 result = cli_spoolss_deleteprinterdriver(
1555 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1557 if ( !W_ERROR_IS_OK(result) ) {
1558 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1559 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1560 argv[1], archi_table[i].long_archi,
1566 printf ("Driver %s removed for arch [%s].\n", argv[1],
1567 archi_table[i].long_archi);
1574 static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
1575 TALLOC_CTX *mem_ctx,
1576 int argc, const char **argv)
1579 char *servername = NULL, *environment = NULL;
1583 /* parse the command arguements */
1585 printf ("Usage: %s [environment]\n", argv[0]);
1589 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1591 strupper_m(servername);
1593 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1594 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1595 SAFE_FREE(servername);
1599 result = cli_spoolss_getprintprocessordirectory(
1600 cli, mem_ctx, 0, &needed, servername, environment, procdir);
1602 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1603 result = cli_spoolss_getprintprocessordirectory(
1604 cli, mem_ctx, needed, NULL, servername, environment,
1607 if (W_ERROR_IS_OK(result))
1608 printf("%s\n", procdir);
1610 SAFE_FREE(servername);
1611 SAFE_FREE(environment);
1618 static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1619 int argc, const char **argv)
1623 char *servername = NULL, *printername = NULL;
1625 BOOL got_handle = False;
1627 /* Parse the command arguements */
1630 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1634 /* Get a printer handle */
1636 asprintf(&servername, "\\\\%s", cli->desthost);
1637 strupper_m(servername);
1638 asprintf(&printername, "%s\\%s", servername, argv[1]);
1640 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1641 MAXIMUM_ALLOWED_ACCESS,
1642 servername, cli->user_name, &handle);
1644 if (!W_ERROR_IS_OK(werror))
1649 /* Dummy up some values for the form data */
1651 form.flags = FORM_USER;
1652 form.size_x = form.size_y = 100;
1658 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1663 werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1667 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1669 SAFE_FREE(servername);
1670 SAFE_FREE(printername);
1677 static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1678 int argc, const char **argv)
1682 char *servername = NULL, *printername = NULL;
1684 BOOL got_handle = False;
1686 /* Parse the command arguements */
1689 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1693 /* Get a printer handle */
1695 asprintf(&servername, "\\\\%s", cli->desthost);
1696 strupper_m(servername);
1697 asprintf(&printername, "%s\\%s", servername, argv[1]);
1699 werror = cli_spoolss_open_printer_ex(
1700 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1701 servername, cli->user_name, &handle);
1703 if (!W_ERROR_IS_OK(werror))
1708 /* Dummy up some values for the form data */
1710 form.flags = FORM_PRINTER;
1711 form.size_x = form.size_y = 100;
1717 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1721 werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1725 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1727 SAFE_FREE(servername);
1728 SAFE_FREE(printername);
1735 static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1736 int argc, const char **argv)
1740 char *servername = NULL, *printername = NULL;
1742 BOOL got_handle = False;
1745 /* Parse the command arguements */
1748 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1752 /* Get a printer handle */
1754 asprintf(&servername, "\\\\%s", cli->desthost);
1755 strupper_m(servername);
1756 asprintf(&printername, "%s\\%s", servername, argv[1]);
1758 werror = cli_spoolss_open_printer_ex(
1759 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1760 servername, cli->user_name, &handle);
1762 if (!W_ERROR_IS_OK(werror))
1769 werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
1770 &handle, argv[2], 1, &form);
1772 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1773 werror = cli_spoolss_getform(cli, mem_ctx, needed, NULL,
1774 &handle, argv[2], 1, &form);
1776 if (!W_ERROR_IS_OK(werror))
1779 printf("width: %d\n", form.width);
1780 printf("length: %d\n", form.length);
1781 printf("left: %d\n", form.left);
1782 printf("top: %d\n", form.top);
1783 printf("right: %d\n", form.right);
1784 printf("bottom: %d\n", form.bottom);
1788 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1790 SAFE_FREE(servername);
1791 SAFE_FREE(printername);
1798 static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
1799 TALLOC_CTX *mem_ctx, int argc,
1804 char *servername = NULL, *printername = NULL;
1805 BOOL got_handle = False;
1807 /* Parse the command arguements */
1810 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1814 /* Get a printer handle */
1816 asprintf(&servername, "\\\\%s", cli->desthost);
1817 strupper_m(servername);
1818 asprintf(&printername, "%s\\%s", servername, argv[1]);
1820 werror = cli_spoolss_open_printer_ex(
1821 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1822 servername, cli->user_name, &handle);
1824 if (!W_ERROR_IS_OK(werror))
1829 /* Delete the form */
1831 werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1835 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1837 SAFE_FREE(servername);
1838 SAFE_FREE(printername);
1843 /* Enumerate forms */
1845 static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
1846 TALLOC_CTX *mem_ctx, int argc,
1851 char *servername = NULL, *printername = NULL;
1852 BOOL got_handle = False;
1853 uint32 needed, num_forms, level = 1, i;
1856 /* Parse the command arguements */
1859 printf ("Usage: %s <printer>\n", argv[0]);
1863 /* Get a printer handle */
1865 asprintf(&servername, "\\\\%s", cli->desthost);
1866 strupper_m(servername);
1867 asprintf(&printername, "%s\\%s", servername, argv[1]);
1869 werror = cli_spoolss_open_printer_ex(
1870 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1871 servername, cli->user_name, &handle);
1873 if (!W_ERROR_IS_OK(werror))
1878 /* Enumerate forms */
1880 werror = cli_spoolss_enumforms(
1881 cli, mem_ctx, 0, &needed, &handle, level, &num_forms, &forms);
1883 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1884 werror = cli_spoolss_enumforms(
1885 cli, mem_ctx, needed, NULL, &handle, level,
1886 &num_forms, &forms);
1888 if (!W_ERROR_IS_OK(werror))
1891 /* Display output */
1893 for (i = 0; i < num_forms; i++) {
1896 if (forms[i].name.buffer)
1897 rpcstr_pull(form_name, forms[i].name.buffer,
1898 sizeof(form_name), -1, STR_TERMINATE);
1900 printf("%s\n", form_name);
1905 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1907 SAFE_FREE(servername);
1908 SAFE_FREE(printername);
1913 static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
1914 TALLOC_CTX *mem_ctx,
1915 int argc, const char **argv)
1919 fstring servername, printername, user;
1921 BOOL opened_hnd = False;
1922 PRINTER_INFO_CTR ctr;
1923 PRINTER_INFO_0 info;
1924 REGISTRY_VALUE value;
1927 /* parse the command arguements */
1929 printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
1933 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1934 strupper_m(servername);
1935 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1936 fstrcpy(user, cli->user_name);
1938 /* get a printer handle */
1939 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1940 MAXIMUM_ALLOWED_ACCESS, servername,
1942 if (!W_ERROR_IS_OK(result))
1947 ctr.printers_0 = &info;
1949 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1952 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1953 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1955 if (!W_ERROR_IS_OK(result))
1958 printf("%s\n", timestring(True));
1959 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
1961 /* Set the printer data */
1963 init_unistr2(&data, argv[3], UNI_STR_TERMINATE);
1964 fstrcpy(value.valuename, argv[2]);
1965 value.type = REG_SZ;
1966 value.size = data.uni_str_len * 2;
1967 value.data_p = talloc_memdup(mem_ctx, data.buffer, value.size);
1969 result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
1971 if (!W_ERROR_IS_OK(result)) {
1972 printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
1975 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
1977 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, 0, &ctr);
1979 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1980 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1982 if (!W_ERROR_IS_OK(result))
1985 printf("%s\n", timestring(True));
1986 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
1991 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1996 static void display_job_info_1(JOB_INFO_1 *job)
1998 fstring username = "", document = "", text_status = "";
2000 rpcstr_pull(username, job->username.buffer,
2001 sizeof(username), -1, STR_TERMINATE);
2003 rpcstr_pull(document, job->document.buffer,
2004 sizeof(document), -1, STR_TERMINATE);
2006 rpcstr_pull(text_status, job->text_status.buffer,
2007 sizeof(text_status), -1, STR_TERMINATE);
2009 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
2010 username, document, text_status, job->pagesprinted,
2014 static void display_job_info_2(JOB_INFO_2 *job)
2016 fstring username = "", document = "", text_status = "";
2018 rpcstr_pull(username, job->username.buffer,
2019 sizeof(username), -1, STR_TERMINATE);
2021 rpcstr_pull(document, job->document.buffer,
2022 sizeof(document), -1, STR_TERMINATE);
2024 rpcstr_pull(text_status, job->text_status.buffer,
2025 sizeof(text_status), -1, STR_TERMINATE);
2027 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
2028 username, document, text_status, job->pagesprinted,
2029 job->totalpages, job->size);
2032 /* Enumerate jobs */
2034 static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
2035 TALLOC_CTX *mem_ctx, int argc,
2039 uint32 needed, level = 1, num_jobs, i;
2040 BOOL got_hnd = False;
2041 pstring printername;
2042 fstring servername, user;
2046 if (argc < 2 || argc > 3) {
2047 printf("Usage: %s printername [level]\n", argv[0]);
2052 level = atoi(argv[2]);
2054 /* Open printer handle */
2056 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2057 strupper_m(servername);
2058 fstrcpy(user, cli->user_name);
2059 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
2060 strupper_m(printername);
2061 pstrcat(printername, argv[1]);
2063 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2064 "", MAXIMUM_ALLOWED_ACCESS,
2065 servername, user, &hnd);
2067 if (!W_ERROR_IS_OK(result))
2072 /* Enumerate ports */
2074 result = cli_spoolss_enumjobs(
2075 cli, mem_ctx, 0, &needed, &hnd, level, 0, 1000,
2078 if (W_ERROR_V(result) == ERRinsufficientbuffer)
2079 result = cli_spoolss_enumjobs(
2080 cli, mem_ctx, needed, NULL, &hnd, level, 0,
2081 1000, &num_jobs, &ctr);
2083 if (!W_ERROR_IS_OK(result))
2086 for (i = 0; i < num_jobs; i++) {
2089 display_job_info_1(&ctr.job.job_info_1[i]);
2092 display_job_info_2(&ctr.job.job_info_2[i]);
2095 d_printf("unknown info level %d\n", level);
2102 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2107 /* enumerate data */
2109 static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
2110 TALLOC_CTX *mem_ctx, int argc,
2114 uint32 i=0, val_needed, data_needed;
2115 BOOL got_hnd = False;
2116 pstring printername;
2117 fstring servername, user;
2121 printf("Usage: %s printername\n", argv[0]);
2125 /* Open printer handle */
2127 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2128 strupper_m(servername);
2129 fstrcpy(user, cli->user_name);
2130 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2131 strupper_m(printername);
2132 pstrcat(printername, argv[1]);
2134 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2135 "", MAXIMUM_ALLOWED_ACCESS,
2136 servername, user, &hnd);
2138 if (!W_ERROR_IS_OK(result))
2143 /* Enumerate data */
2145 result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2146 &val_needed, &data_needed,
2148 while (W_ERROR_IS_OK(result)) {
2149 REGISTRY_VALUE value;
2150 result = cli_spoolss_enumprinterdata(
2151 cli, mem_ctx, &hnd, i++, val_needed,
2152 data_needed, 0, 0, &value);
2153 if (W_ERROR_IS_OK(result))
2154 display_reg_value(value);
2156 if (W_ERROR_V(result) == ERRnomoreitems)
2157 result = W_ERROR(ERRsuccess);
2161 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2166 /* enumerate data for a given key */
2168 static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
2169 TALLOC_CTX *mem_ctx, int argc,
2174 BOOL got_hnd = False;
2175 pstring printername;
2176 fstring servername, user;
2177 const char *keyname = NULL;
2182 printf("Usage: %s printername <keyname>\n", argv[0]);
2188 /* Open printer handle */
2190 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2191 strupper_m(servername);
2192 fstrcpy(user, cli->user_name);
2193 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2194 strupper_m(printername);
2195 pstrcat(printername, argv[1]);
2197 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2198 "", MAXIMUM_ALLOWED_ACCESS,
2199 servername, user, &hnd);
2201 if (!W_ERROR_IS_OK(result))
2206 /* Enumerate subkeys */
2208 result = cli_spoolss_enumprinterdataex(
2209 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL);
2211 if (W_ERROR_V(result) == ERRmoredata)
2212 result = cli_spoolss_enumprinterdataex(
2213 cli, mem_ctx, needed, NULL, &hnd, keyname, &ctr);
2215 if (!W_ERROR_IS_OK(result))
2218 for (i=0; i < ctr.num_values; i++) {
2219 display_reg_value(*(ctr.values[i]));
2222 regval_ctr_destroy(&ctr);
2226 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2231 /* enumerate subkeys */
2233 static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
2234 TALLOC_CTX *mem_ctx, int argc,
2238 uint32 needed, returned;
2239 BOOL got_hnd = False;
2240 pstring printername;
2241 fstring servername, user;
2242 const char *keyname = NULL;
2244 uint16 *keylist = NULL, *curkey;
2246 if (argc < 2 || argc > 3) {
2247 printf("Usage: %s printername [keyname]\n", argv[0]);
2256 /* Open printer handle */
2258 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2259 strupper_m(servername);
2260 fstrcpy(user, cli->user_name);
2261 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2262 strupper_m(printername);
2263 pstrcat(printername, argv[1]);
2265 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2266 "", MAXIMUM_ALLOWED_ACCESS,
2267 servername, user, &hnd);
2269 if (!W_ERROR_IS_OK(result))
2274 /* Enumerate subkeys */
2276 result = cli_spoolss_enumprinterkey(
2277 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL, NULL);
2279 if (W_ERROR_V(result) == ERRmoredata)
2280 result = cli_spoolss_enumprinterkey(
2281 cli, mem_ctx, needed, NULL, &hnd, keyname, &keylist,
2284 if (!W_ERROR_IS_OK(result))
2288 while (*curkey != 0) {
2290 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2292 printf("%s\n", subkey);
2293 curkey += strlen(subkey) + 1;
2300 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2305 static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
2306 TALLOC_CTX *mem_ctx, int argc,
2309 fstring servername, printername;
2311 BOOL got_hnd = False;
2313 SPOOL_NOTIFY_OPTION option;
2316 printf("Usage: %s printername\n", argv[0]);
2323 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2324 strupper_m(servername);
2326 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
2328 strupper_m(printername);
2330 result = cli_spoolss_open_printer_ex(
2331 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2332 servername, cli->user_name, &hnd);
2334 if (!W_ERROR_IS_OK(result)) {
2335 printf("Error opening %s\n", argv[1]);
2341 /* Create spool options */
2343 ZERO_STRUCT(option);
2346 option.option_type_ptr = 1;
2347 option.count = option.ctr.count = 2;
2349 option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc(
2350 mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2);
2352 ZERO_STRUCT(option.ctr.type[0]);
2353 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2354 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2355 option.ctr.type[0].fields_ptr = 1;
2356 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2358 ZERO_STRUCT(option.ctr.type[1]);
2359 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2360 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2361 option.ctr.type[1].fields_ptr = 1;
2362 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2366 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2367 strupper_m(servername);
2369 result = cli_spoolss_rffpcnex(
2370 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2372 if (!W_ERROR_IS_OK(result)) {
2373 printf("Error rffpcnex %s\n", argv[1]);
2379 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2384 /* List of commands exported by this module */
2385 struct cmd_set spoolss_commands[] = {
2389 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
2390 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
2391 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
2392 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
2393 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
2394 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
2395 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
2396 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
2397 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
2398 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
2399 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
2400 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
2401 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
2402 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
2403 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
2404 { "getprintprocdir",RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2405 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
2406 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
2407 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2408 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
2409 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
2410 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
2411 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
2412 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
2413 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
2414 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, PI_SPOOLSS, "Set printername", "" },
2415 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
2416 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },