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 R4000", "W32MIPS", 2 },
39 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
40 {"Windows NT PowerPC", "W32PPC", 2 },
47 * rpcclient module for SPOOLSS rpc pipe.
49 * This generally just parses and checks command lines, and then calls
50 * a cli_spoolss function.
53 /****************************************************************************
54 function to do the mapping between the long architecture name and
56 ****************************************************************************/
57 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
61 DEBUG(107,("Getting architecture dependant directory\n"));
64 } while ( (archi_table[i].long_archi!=NULL ) &&
65 StrCaseCmp(long_archi, archi_table[i].long_archi) );
67 if (archi_table[i].long_archi==NULL) {
68 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
72 /* this might be client code - but shouldn't this be an fstrcpy etc? */
75 DEBUGADD(108,("index: [%d]\n", i));
76 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
77 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
79 return archi_table[i].short_archi;
83 /**********************************************************************
84 * dummy function -- placeholder
86 static WERROR cmd_spoolss_not_implemented(struct cli_state *cli,
88 int argc, const char **argv)
90 printf ("(*) This command is not currently implemented.\n");
95 /***********************************************************************
96 * Get printer information
98 static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
100 int argc, const char **argv)
104 fstring servername, user;
108 printf("Usage: %s <printername>\n", argv[0]);
113 return WERR_GENERAL_FAILURE;
115 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
116 strupper_m(servername);
117 fstrcpy(user, cli->user_name);
118 fstrcpy(printername, argv[1]);
120 /* Open the printer handle */
122 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
123 "", PRINTER_ALL_ACCESS,
124 servername, user, &hnd);
126 if (W_ERROR_IS_OK(werror)) {
127 printf("Printer %s opened successfully\n", printername);
128 werror = cli_spoolss_close_printer(cli, mem_ctx, &hnd);
130 if (!W_ERROR_IS_OK(werror)) {
131 printf("Error closing printer handle! (%s)\n",
132 get_dos_error_msg(werror));
140 /****************************************************************************
141 printer info level 0 display function
142 ****************************************************************************/
143 static void display_print_info_0(PRINTER_INFO_0 *i0)
146 fstring servername = "";
151 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
153 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
155 printf("\tprintername:[%s]\n", name);
156 printf("\tservername:[%s]\n", servername);
157 printf("\tcjobs:[0x%x]\n", i0->cjobs);
158 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
160 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
161 i0->day, i0->dayofweek);
162 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
163 i0->second, i0->milliseconds);
165 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
166 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
168 printf("\tmajorversion:[0x%x]\n", i0->major_version);
169 printf("\tbuildversion:[0x%x]\n", i0->build_version);
171 printf("\tunknown7:[0x%x]\n", i0->unknown7);
172 printf("\tunknown8:[0x%x]\n", i0->unknown8);
173 printf("\tunknown9:[0x%x]\n", i0->unknown9);
174 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
175 printf("\tunknown11:[0x%x]\n", i0->unknown11);
176 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
177 printf("\tunknown13:[0x%x]\n", i0->unknown13);
178 printf("\tunknown14:[0x%x]\n", i0->unknown14);
179 printf("\tunknown15:[0x%x]\n", i0->unknown15);
180 printf("\tunknown16:[0x%x]\n", i0->unknown16);
181 printf("\tchange_id:[0x%x]\n", i0->change_id);
182 printf("\tunknown18:[0x%x]\n", i0->unknown18);
183 printf("\tstatus:[0x%x]\n", i0->status);
184 printf("\tunknown20:[0x%x]\n", i0->unknown20);
185 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
186 printf("\tunknown22:[0x%x]\n", i0->unknown22);
187 printf("\tunknown23:[0x%x]\n", i0->unknown23);
188 printf("\tunknown24:[0x%x]\n", i0->unknown24);
189 printf("\tunknown25:[0x%x]\n", i0->unknown25);
190 printf("\tunknown26:[0x%x]\n", i0->unknown26);
191 printf("\tunknown27:[0x%x]\n", i0->unknown27);
192 printf("\tunknown28:[0x%x]\n", i0->unknown28);
193 printf("\tunknown29:[0x%x]\n", i0->unknown29);
198 /****************************************************************************
199 printer info level 1 display function
200 ****************************************************************************/
201 static void display_print_info_1(PRINTER_INFO_1 *i1)
207 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
210 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
211 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
213 printf("\tflags:[0x%x]\n", i1->flags);
214 printf("\tname:[%s]\n", name);
215 printf("\tdescription:[%s]\n", desc);
216 printf("\tcomment:[%s]\n", comm);
221 /****************************************************************************
222 printer info level 2 display function
223 ****************************************************************************/
224 static void display_print_info_2(PRINTER_INFO_2 *i2)
226 fstring servername = "";
227 fstring printername = "";
228 fstring sharename = "";
229 fstring portname = "";
230 fstring drivername = "";
231 fstring comment = "";
232 fstring location = "";
233 fstring sepfile = "";
234 fstring printprocessor = "";
235 fstring datatype = "";
236 fstring parameters = "";
238 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
240 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
242 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
244 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
246 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
248 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
250 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
252 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
254 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
256 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
258 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
260 printf("\tservername:[%s]\n", servername);
261 printf("\tprintername:[%s]\n", printername);
262 printf("\tsharename:[%s]\n", sharename);
263 printf("\tportname:[%s]\n", portname);
264 printf("\tdrivername:[%s]\n", drivername);
265 printf("\tcomment:[%s]\n", comment);
266 printf("\tlocation:[%s]\n", location);
267 printf("\tsepfile:[%s]\n", sepfile);
268 printf("\tprintprocessor:[%s]\n", printprocessor);
269 printf("\tdatatype:[%s]\n", datatype);
270 printf("\tparameters:[%s]\n", parameters);
271 printf("\tattributes:[0x%x]\n", i2->attributes);
272 printf("\tpriority:[0x%x]\n", i2->priority);
273 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
274 printf("\tstarttime:[0x%x]\n", i2->starttime);
275 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
276 printf("\tstatus:[0x%x]\n", i2->status);
277 printf("\tcjobs:[0x%x]\n", i2->cjobs);
278 printf("\taverageppm:[0x%x]\n", i2->averageppm);
281 display_sec_desc(i2->secdesc);
286 /****************************************************************************
287 printer info level 3 display function
288 ****************************************************************************/
289 static void display_print_info_3(PRINTER_INFO_3 *i3)
291 printf("\tflags:[0x%x]\n", i3->flags);
293 display_sec_desc(i3->secdesc);
298 /* Enumerate printers */
300 static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
302 int argc, const char **argv)
305 uint32 info_level = 1;
306 PRINTER_INFO_CTR ctr;
307 uint32 i = 0, num_printers, needed;
312 printf("Usage: %s [level] [name]\n", argv[0]);
317 info_level = atoi(argv[1]);
320 fstrcpy(name, argv[2]);
322 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
326 /* Enumerate printers -- Should we enumerate types other
327 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
331 result = cli_spoolss_enum_printers(
332 cli, mem_ctx, 0, &needed, name, PRINTER_ENUM_LOCAL,
333 info_level, &num_printers, &ctr);
335 if (W_ERROR_V(result) == ERRinsufficientbuffer)
336 result = cli_spoolss_enum_printers(
337 cli, mem_ctx, needed, NULL, name, PRINTER_ENUM_LOCAL,
338 info_level, &num_printers, &ctr);
340 if (W_ERROR_IS_OK(result)) {
343 printf ("No printers returned.\n");
347 for (i = 0; i < num_printers; i++) {
350 display_print_info_0(&ctr.printers_0[i]);
353 display_print_info_1(&ctr.printers_1[i]);
356 display_print_info_2(&ctr.printers_2[i]);
359 display_print_info_3(&ctr.printers_3[i]);
362 printf("unknown info level %d\n", info_level);
372 /****************************************************************************
373 port info level 1 display function
374 ****************************************************************************/
375 static void display_port_info_1(PORT_INFO_1 *i1)
379 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
380 printf("\tPort Name:\t[%s]\n", buffer);
383 /****************************************************************************
384 port info level 2 display function
385 ****************************************************************************/
386 static void display_port_info_2(PORT_INFO_2 *i2)
390 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
391 printf("\tPort Name:\t[%s]\n", buffer);
392 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
394 printf("\tMonitor Name:\t[%s]\n", buffer);
395 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
397 printf("\tDescription:\t[%s]\n", buffer);
398 printf("\tPort Type:\t" );
399 if ( i2->port_type ) {
400 int comma = 0; /* hack */
402 if ( i2->port_type & PORT_TYPE_READ ) {
406 if ( i2->port_type & PORT_TYPE_WRITE ) {
407 printf( "%sWrite", comma ? ", " : "" );
410 /* These two have slightly different interpretations
411 on 95/98/ME but I'm disregarding that for now */
412 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
413 printf( "%sRedirected", comma ? ", " : "" );
416 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
417 printf( "%sNet-Attached", comma ? ", " : "" );
421 printf( "[Unset]\n" );
423 printf("\tReserved:\t[%d]\n", i2->reserved);
427 /* Enumerate ports */
429 static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
430 TALLOC_CTX *mem_ctx, int argc,
434 uint32 needed, info_level = 1;
439 printf("Usage: %s [level]\n", argv[0]);
444 info_level = atoi(argv[1]);
446 /* Enumerate ports */
450 result = cli_spoolss_enum_ports(cli, mem_ctx, 0, &needed, info_level,
453 if (W_ERROR_V(result) == ERRinsufficientbuffer)
454 result = cli_spoolss_enum_ports(cli, mem_ctx, needed, NULL,
455 info_level, &returned, &ctr);
457 if (W_ERROR_IS_OK(result)) {
460 for (i = 0; i < returned; i++) {
461 switch (info_level) {
463 display_port_info_1(&ctr.port.info_1[i]);
466 display_port_info_2(&ctr.port.info_2[i]);
469 printf("unknown info level %d\n", info_level);
478 /***********************************************************************
479 * Set printer comment - use a level2 set.
481 static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
483 int argc, const char **argv)
488 uint32 info_level = 2;
489 BOOL opened_hnd = False;
490 PRINTER_INFO_CTR ctr;
496 if (argc == 1 || argc > 3) {
497 printf("Usage: %s printername comment\n", argv[0]);
502 /* Open a printer handle */
504 fstrcpy(comment, argv[2]);
507 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
508 strupper_m(servername);
509 fstrcpy(printername, argv[1]);
510 fstrcpy(user, cli->user_name);
512 /* get a printer handle */
513 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
514 PRINTER_ALL_ACCESS, servername,
517 if (!W_ERROR_IS_OK(result))
522 /* Get printer info */
523 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, info_level, &ctr);
525 if (W_ERROR_V(result) == ERRinsufficientbuffer)
526 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
528 if (!W_ERROR_IS_OK(result))
532 /* Modify the comment. */
533 init_unistr(&ctr.printers_2->comment, comment);
534 ctr.printers_2->devmode = NULL;
535 ctr.printers_2->secdesc = NULL;
537 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
538 if (W_ERROR_IS_OK(result))
539 printf("Success in setting comment.\n");
543 cli_spoolss_close_printer(cli, mem_ctx, &pol);
548 /***********************************************************************
549 * Get printer information
551 static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
553 int argc, const char **argv)
557 uint32 info_level = 1;
558 BOOL opened_hnd = False;
559 PRINTER_INFO_CTR ctr;
565 if (argc == 1 || argc > 3) {
566 printf("Usage: %s <printername> [level]\n", argv[0]);
570 /* Open a printer handle */
572 info_level = atoi(argv[2]);
575 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
576 strupper_m(servername);
577 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
578 fstrcpy(user, cli->user_name);
580 /* get a printer handle */
582 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
583 "", MAXIMUM_ALLOWED_ACCESS,
584 servername, user, &pol);
586 if (!W_ERROR_IS_OK(result))
591 /* Get printer info */
593 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
594 &pol, info_level, &ctr);
596 if (W_ERROR_V(result) == ERRinsufficientbuffer)
597 result = cli_spoolss_getprinter(
598 cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
600 if (!W_ERROR_IS_OK(result))
603 /* Display printer info */
605 switch (info_level) {
607 display_print_info_0(ctr.printers_0);
610 display_print_info_1(ctr.printers_1);
613 display_print_info_2(ctr.printers_2);
616 display_print_info_3(ctr.printers_3);
619 printf("unknown info level %d\n", info_level);
625 cli_spoolss_close_printer(cli, mem_ctx, &pol);
630 static void display_reg_value(REGISTRY_VALUE value)
636 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
637 *((uint32 *) value.data_p));
640 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
642 printf("%s: REG_SZ: %s\n", value.valuename, text);
645 printf("%s: REG_BINARY: unknown length value not displayed\n",
649 uint16 *curstr = (uint16 *) value.data_p;
650 uint8 *start = value.data_p;
651 printf("%s: REG_MULTI_SZ:\n", value.valuename);
652 while ((*curstr != 0) &&
653 ((uint8 *) curstr < start + value.size)) {
654 rpcstr_pull(text, curstr, sizeof(text), -1,
656 printf(" %s\n", text);
657 curstr += strlen(text) + 1;
662 printf("%s: unknown type %d\n", value.valuename, value.type);
667 /***********************************************************************
670 static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
672 int argc, const char **argv)
676 BOOL opened_hnd = False;
681 const char *valuename;
682 REGISTRY_VALUE value;
685 printf("Usage: %s <printername> <valuename>\n", argv[0]);
686 printf("<printername> of . queries print server\n");
691 /* Open a printer handle */
693 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
694 strupper_m(servername);
695 if (strncmp(argv[1], ".", sizeof(".")) == 0)
696 fstrcpy(printername, servername);
698 slprintf(printername, sizeof(servername)-1, "%s\\%s",
699 servername, argv[1]);
700 fstrcpy(user, cli->user_name);
702 /* get a printer handle */
704 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
705 "", MAXIMUM_ALLOWED_ACCESS,
706 servername, user, &pol);
708 if (!W_ERROR_IS_OK(result))
713 /* Get printer info */
715 result = cli_spoolss_getprinterdata(cli, mem_ctx, 0, &needed,
716 &pol, valuename, &value);
718 if (W_ERROR_V(result) == ERRmoredata)
719 result = cli_spoolss_getprinterdata(
720 cli, mem_ctx, needed, NULL, &pol, valuename, &value);
722 if (!W_ERROR_IS_OK(result))
725 /* Display printer data */
727 fstrcpy(value.valuename, valuename);
728 display_reg_value(value);
733 cli_spoolss_close_printer(cli, mem_ctx, &pol);
738 /***********************************************************************
741 static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
743 int argc, const char **argv)
747 BOOL opened_hnd = False;
752 const char *valuename, *keyname;
753 REGISTRY_VALUE value;
756 printf("Usage: %s <printername> <keyname> <valuename>\n",
758 printf("<printername> of . queries print server\n");
764 /* Open a printer handle */
766 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
767 strupper_m(servername);
768 if (strncmp(argv[1], ".", sizeof(".")) == 0)
769 fstrcpy(printername, servername);
771 slprintf(printername, sizeof(printername)-1, "%s\\%s",
772 servername, argv[1]);
773 fstrcpy(user, cli->user_name);
775 /* get a printer handle */
777 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
778 "", MAXIMUM_ALLOWED_ACCESS,
779 servername, user, &pol);
781 if (!W_ERROR_IS_OK(result))
786 /* Get printer info */
788 result = cli_spoolss_getprinterdataex(cli, mem_ctx, 0, &needed,
789 &pol, keyname, valuename,
792 if (W_ERROR_V(result) == ERRmoredata)
793 result = cli_spoolss_getprinterdataex(cli, mem_ctx, needed,
797 if (!W_ERROR_IS_OK(result))
800 /* Display printer data */
802 fstrcpy(value.valuename, valuename);
803 display_reg_value(value);
808 cli_spoolss_close_printer(cli, mem_ctx, &pol);
813 /****************************************************************************
814 printer info level 0 display function
815 ****************************************************************************/
816 static void display_print_driver_1(DRIVER_INFO_1 *i1)
822 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
824 printf ("Printer Driver Info 1:\n");
825 printf ("\tDriver Name: [%s]\n\n", name);
830 /****************************************************************************
831 printer info level 1 display function
832 ****************************************************************************/
833 static void display_print_driver_2(DRIVER_INFO_2 *i1)
836 fstring architecture;
843 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
844 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
845 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
846 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
847 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
849 printf ("Printer Driver Info 2:\n");
850 printf ("\tVersion: [%x]\n", i1->version);
851 printf ("\tDriver Name: [%s]\n", name);
852 printf ("\tArchitecture: [%s]\n", architecture);
853 printf ("\tDriver Path: [%s]\n", driverpath);
854 printf ("\tDatafile: [%s]\n", datafile);
855 printf ("\tConfigfile: [%s]\n\n", configfile);
860 /****************************************************************************
861 printer info level 2 display function
862 ****************************************************************************/
863 static void display_print_driver_3(DRIVER_INFO_3 *i1)
866 fstring architecture = "";
867 fstring driverpath = "";
868 fstring datafile = "";
869 fstring configfile = "";
870 fstring helpfile = "";
871 fstring dependentfiles = "";
872 fstring monitorname = "";
873 fstring defaultdatatype = "";
881 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
882 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
883 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
884 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
885 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
886 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
887 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
888 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
890 printf ("Printer Driver Info 3:\n");
891 printf ("\tVersion: [%x]\n", i1->version);
892 printf ("\tDriver Name: [%s]\n",name);
893 printf ("\tArchitecture: [%s]\n", architecture);
894 printf ("\tDriver Path: [%s]\n", driverpath);
895 printf ("\tDatafile: [%s]\n", datafile);
896 printf ("\tConfigfile: [%s]\n", configfile);
897 printf ("\tHelpfile: [%s]\n\n", helpfile);
901 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
903 length+=strlen(dependentfiles)+1;
905 if (strlen(dependentfiles) > 0)
907 printf ("\tDependentfiles: [%s]\n", dependentfiles);
917 printf ("\tMonitorname: [%s]\n", monitorname);
918 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
923 /***********************************************************************
924 * Get printer information
926 static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
928 int argc, const char **argv)
932 uint32 info_level = 3;
933 BOOL opened_hnd = False;
934 PRINTER_DRIVER_CTR ctr;
940 if ((argc == 1) || (argc > 3))
942 printf("Usage: %s <printername> [level]\n", argv[0]);
946 /* get the arguments need to open the printer handle */
947 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
948 strupper_m(servername);
949 fstrcpy(user, cli->user_name);
950 fstrcpy(printername, argv[1]);
952 info_level = atoi(argv[2]);
954 /* Open a printer handle */
956 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
958 servername, user, &pol);
960 if (!W_ERROR_IS_OK(werror)) {
961 printf("Error opening printer handle for %s!\n", printername);
967 /* loop through and print driver info level for each architecture */
969 for (i=0; archi_table[i].long_archi!=NULL; i++) {
972 werror = cli_spoolss_getprinterdriver(
973 cli, mem_ctx, 0, &needed, &pol, info_level,
974 archi_table[i].long_archi, &ctr);
976 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
977 werror = cli_spoolss_getprinterdriver(
978 cli, mem_ctx, needed, NULL, &pol, info_level,
979 archi_table[i].long_archi, &ctr);
981 if (!W_ERROR_IS_OK(werror))
984 printf ("\n[%s]\n", archi_table[i].long_archi);
986 switch (info_level) {
988 display_print_driver_1 (ctr.info1);
991 display_print_driver_2 (ctr.info2);
994 display_print_driver_3 (ctr.info3);
997 printf("unknown info level %d\n", info_level);
1005 cli_spoolss_close_printer (cli, mem_ctx, &pol);
1010 /***********************************************************************
1011 * Get printer information
1013 static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
1014 TALLOC_CTX *mem_ctx,
1015 int argc, const char **argv)
1018 uint32 info_level = 1;
1019 PRINTER_DRIVER_CTR ctr;
1025 printf("Usage: enumdrivers [level]\n");
1030 info_level = atoi(argv[1]);
1033 /* loop through and print driver info level for each architecture */
1034 for (i=0; archi_table[i].long_archi!=NULL; i++)
1038 werror = cli_spoolss_enumprinterdrivers(
1039 cli, mem_ctx, 0, &needed, info_level,
1040 archi_table[i].long_archi, &returned, &ctr);
1042 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1043 werror = cli_spoolss_enumprinterdrivers(
1044 cli, mem_ctx, needed, NULL, info_level,
1045 archi_table[i].long_archi, &returned, &ctr);
1050 if (!W_ERROR_IS_OK(werror)) {
1051 printf ("Error getting driver for environment [%s] - %d\n",
1052 archi_table[i].long_archi, W_ERROR_V(werror));
1056 printf ("\n[%s]\n", archi_table[i].long_archi);
1061 for (j=0; j < returned; j++) {
1062 display_print_driver_1 (&(ctr.info1[j]));
1066 for (j=0; j < returned; j++) {
1067 display_print_driver_2 (&(ctr.info2[j]));
1071 for (j=0; j < returned; j++) {
1072 display_print_driver_3 (&(ctr.info3[j]));
1076 printf("unknown info level %d\n", info_level);
1084 /****************************************************************************
1085 printer info level 1 display function
1086 ****************************************************************************/
1087 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1093 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1095 printf ("\tDirectory Name:[%s]\n", name);
1098 /***********************************************************************
1099 * Get printer driver directory information
1101 static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
1102 TALLOC_CTX *mem_ctx,
1103 int argc, const char **argv)
1107 DRIVER_DIRECTORY_CTR ctr;
1111 printf("Usage: %s [environment]\n", argv[0]);
1115 /* Get the arguments need to open the printer handle */
1118 fstrcpy (env, argv[1]);
1120 fstrcpy (env, "Windows NT x86");
1122 /* Get the directory. Only use Info level 1 */
1124 result = cli_spoolss_getprinterdriverdir(
1125 cli, mem_ctx, 0, &needed, 1, env, &ctr);
1127 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1128 result = cli_spoolss_getprinterdriverdir(
1129 cli, mem_ctx, needed, NULL, 1, env, &ctr);
1131 if (W_ERROR_IS_OK(result))
1132 display_printdriverdir_1(ctr.info1);
1137 /*******************************************************************************
1138 set the version and environment fields of a DRIVER_INFO_3 struct
1139 ******************************************************************************/
1140 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1145 for (i=0; archi_table[i].long_archi != NULL; i++)
1147 if (strcmp(arch, archi_table[i].short_archi) == 0)
1149 info->version = archi_table[i].version;
1150 init_unistr (&info->architecture, archi_table[i].long_archi);
1155 if (archi_table[i].long_archi == NULL)
1157 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1164 /**************************************************************************
1165 wrapper for strtok to get the next parameter from a delimited list.
1166 Needed to handle the empty parameter string denoted by "NULL"
1167 *************************************************************************/
1168 static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
1172 /* get the next token */
1173 ptr = strtok(str, delim);
1175 /* a string of 'NULL' is used to represent an empty
1176 parameter because two consecutive delimiters
1177 will not return an empty string. See man strtok(3)
1179 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
1183 init_unistr(dest, ptr);
1188 /********************************************************************************
1189 fill in the members of a DRIVER_INFO_3 struct using a character
1190 string in the form of
1191 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1192 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1193 <Default Data Type>:<Comma Separated list of Files>
1194 *******************************************************************************/
1195 static BOOL init_drv_info_3_members (
1196 TALLOC_CTX *mem_ctx,
1197 DRIVER_INFO_3 *info,
1204 /* fill in the UNISTR fields */
1205 str = get_driver_3_param (args, ":", &info->name);
1206 str = get_driver_3_param (NULL, ":", &info->driverpath);
1207 str = get_driver_3_param (NULL, ":", &info->datafile);
1208 str = get_driver_3_param (NULL, ":", &info->configfile);
1209 str = get_driver_3_param (NULL, ":", &info->helpfile);
1210 str = get_driver_3_param (NULL, ":", &info->monitorname);
1211 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1213 /* <Comma Separated List of Dependent Files> */
1214 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1217 /* begin to strip out each filename */
1218 str = strtok(str, ",");
1222 /* keep a cumlative count of the str lengths */
1223 len += strlen(str)+1;
1224 str = strtok(NULL, ",");
1227 /* allocate the space; add one extra slot for a terminating NULL.
1228 Each filename is NULL terminated and the end contains a double
1230 if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL)
1232 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1235 for (i=0; i<len; i++)
1237 info->dependentfiles[i] = SSVAL(&info->dependentfiles[i], 0, str2[i]);
1239 info->dependentfiles[len] = '\0';
1245 static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
1246 TALLOC_CTX *mem_ctx,
1247 int argc, const char **argv)
1251 PRINTER_DRIVER_CTR ctr;
1252 DRIVER_INFO_3 info3;
1254 fstring driver_name;
1256 /* parse the command arguements */
1259 printf ("Usage: %s <Environment>\\\n", argv[0]);
1260 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1261 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1262 printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
1267 /* Fill in the DRIVER_INFO_3 struct */
1269 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
1271 printf ("Error Unknown architechture [%s]\n", argv[1]);
1272 return WERR_INVALID_PARAM;
1275 set_drv_info_3_env(&info3, arch);
1277 if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
1279 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1280 return WERR_INVALID_PARAM;
1285 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1287 if (W_ERROR_IS_OK(result)) {
1288 rpcstr_pull(driver_name, info3.name.buffer,
1289 sizeof(driver_name), -1, STR_TERMINATE);
1290 printf ("Printer Driver %s successfully installed.\n",
1298 static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
1299 TALLOC_CTX *mem_ctx,
1300 int argc, const char **argv)
1304 PRINTER_INFO_CTR ctr;
1305 PRINTER_INFO_2 info2;
1308 /* parse the command arguements */
1311 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1315 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1316 strupper_m(servername);
1318 /* Fill in the DRIVER_INFO_3 struct */
1321 init_unistr( &info2.servername, servername);
1323 init_unistr( &info2.printername, argv[1]);
1324 init_unistr( &info2.sharename, argv[2]);
1325 init_unistr( &info2.drivername, argv[3]);
1326 init_unistr( &info2.portname, argv[4]);
1327 init_unistr( &info2.comment, "Created by rpcclient");
1328 init_unistr( &info2.printprocessor, "winprint");
1329 init_unistr( &info2.datatype, "RAW");
1330 info2.devmode = NULL;
1331 info2.secdesc = NULL;
1332 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1334 info2.defaultpriority = 0;
1335 info2.starttime = 0;
1336 info2.untiltime = 0;
1338 /* These three fields must not be used by AddPrinter()
1339 as defined in the MS Platform SDK documentation..
1343 info2.averageppm = 0;
1346 ctr.printers_2 = &info2;
1347 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1349 if (W_ERROR_IS_OK(result))
1350 printf ("Printer %s successfully installed.\n", argv[1]);
1355 static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
1356 TALLOC_CTX *mem_ctx,
1357 int argc, const char **argv)
1362 BOOL opened_hnd = False;
1363 PRINTER_INFO_CTR ctr;
1364 PRINTER_INFO_2 info2;
1370 /* parse the command arguements */
1373 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1377 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1378 strupper_m(servername);
1379 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1380 fstrcpy(user, cli->user_name);
1382 /* Get a printer handle */
1384 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1386 servername, user, &pol);
1388 if (!W_ERROR_IS_OK(result))
1393 /* Get printer info */
1395 ZERO_STRUCT (info2);
1396 ctr.printers_2 = &info2;
1398 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1401 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1402 result = cli_spoolss_getprinter(
1403 cli, mem_ctx, needed, NULL, &pol, level, &ctr);
1405 if (!W_ERROR_IS_OK(result)) {
1406 printf ("Unable to retrieve printer information!\n");
1410 /* Set the printer driver */
1412 init_unistr(&ctr.printers_2->drivername, argv[2]);
1414 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1416 if (!W_ERROR_IS_OK(result)) {
1417 printf("SetPrinter call failed!\n");
1421 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1427 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1433 static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
1434 TALLOC_CTX *mem_ctx,
1435 int argc, const char **argv)
1441 /* parse the command arguements */
1444 printf ("Usage: %s <driver>\n", argv[0]);
1448 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1449 strupper_m(servername);
1451 /* delete the driver for all architectures */
1452 for (i=0; archi_table[i].long_archi; i++)
1454 /* make the call to remove the driver */
1455 result = cli_spoolss_deleteprinterdriver(
1456 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1458 if ( !W_ERROR_IS_OK(result) ) {
1459 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1460 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1461 argv[1], archi_table[i].long_archi,
1467 printf ("Driver %s removed for arch [%s].\n", argv[1],
1468 archi_table[i].long_archi);
1475 static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
1476 TALLOC_CTX *mem_ctx,
1477 int argc, const char **argv)
1480 char *servername = NULL, *environment = NULL;
1484 /* parse the command arguements */
1486 printf ("Usage: %s [environment]\n", argv[0]);
1490 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1492 strupper_m(servername);
1494 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1495 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1496 SAFE_FREE(servername);
1500 result = cli_spoolss_getprintprocessordirectory(
1501 cli, mem_ctx, 0, &needed, servername, environment, procdir);
1503 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1504 result = cli_spoolss_getprintprocessordirectory(
1505 cli, mem_ctx, needed, NULL, servername, environment,
1508 if (W_ERROR_IS_OK(result))
1509 printf("%s\n", procdir);
1511 SAFE_FREE(servername);
1512 SAFE_FREE(environment);
1519 static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1520 int argc, const char **argv)
1524 char *servername = NULL, *printername = NULL;
1526 BOOL got_handle = False;
1528 /* Parse the command arguements */
1531 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1535 /* Get a printer handle */
1537 asprintf(&servername, "\\\\%s", cli->desthost);
1538 strupper_m(servername);
1539 asprintf(&printername, "%s\\%s", servername, argv[1]);
1541 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1542 MAXIMUM_ALLOWED_ACCESS,
1543 servername, cli->user_name, &handle);
1545 if (!W_ERROR_IS_OK(werror))
1550 /* Dummy up some values for the form data */
1552 form.flags = FORM_USER;
1553 form.size_x = form.size_y = 100;
1559 init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
1564 werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1568 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1570 SAFE_FREE(servername);
1571 SAFE_FREE(printername);
1578 static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1579 int argc, const char **argv)
1583 char *servername = NULL, *printername = NULL;
1585 BOOL got_handle = False;
1587 /* Parse the command arguements */
1590 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1594 /* Get a printer handle */
1596 asprintf(&servername, "\\\\%s", cli->desthost);
1597 strupper_m(servername);
1598 asprintf(&printername, "%s\\%s", servername, argv[1]);
1600 werror = cli_spoolss_open_printer_ex(
1601 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1602 servername, cli->user_name, &handle);
1604 if (!W_ERROR_IS_OK(werror))
1609 /* Dummy up some values for the form data */
1611 form.flags = FORM_PRINTER;
1612 form.size_x = form.size_y = 100;
1618 init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
1622 werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1626 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1628 SAFE_FREE(servername);
1629 SAFE_FREE(printername);
1636 static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1637 int argc, const char **argv)
1641 char *servername = NULL, *printername = NULL;
1643 BOOL got_handle = False;
1646 /* Parse the command arguements */
1649 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1653 /* Get a printer handle */
1655 asprintf(&servername, "\\\\%s", cli->desthost);
1656 strupper_m(servername);
1657 asprintf(&printername, "%s\\%s", servername, argv[1]);
1659 werror = cli_spoolss_open_printer_ex(
1660 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1661 servername, cli->user_name, &handle);
1663 if (!W_ERROR_IS_OK(werror))
1670 werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
1671 &handle, argv[2], 1, &form);
1673 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1674 werror = cli_spoolss_getform(cli, mem_ctx, needed, NULL,
1675 &handle, argv[2], 1, &form);
1677 if (!W_ERROR_IS_OK(werror))
1680 printf("width: %d\n", form.width);
1681 printf("length: %d\n", form.length);
1682 printf("left: %d\n", form.left);
1683 printf("top: %d\n", form.top);
1684 printf("right: %d\n", form.right);
1685 printf("bottom: %d\n", form.bottom);
1689 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1691 SAFE_FREE(servername);
1692 SAFE_FREE(printername);
1699 static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
1700 TALLOC_CTX *mem_ctx, int argc,
1705 char *servername = NULL, *printername = NULL;
1706 BOOL got_handle = False;
1708 /* Parse the command arguements */
1711 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1715 /* Get a printer handle */
1717 asprintf(&servername, "\\\\%s", cli->desthost);
1718 strupper_m(servername);
1719 asprintf(&printername, "%s\\%s", servername, argv[1]);
1721 werror = cli_spoolss_open_printer_ex(
1722 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1723 servername, cli->user_name, &handle);
1725 if (!W_ERROR_IS_OK(werror))
1730 /* Delete the form */
1732 werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1736 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1738 SAFE_FREE(servername);
1739 SAFE_FREE(printername);
1744 /* Enumerate forms */
1746 static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
1747 TALLOC_CTX *mem_ctx, int argc,
1752 char *servername = NULL, *printername = NULL;
1753 BOOL got_handle = False;
1754 uint32 needed, num_forms, level = 1, i;
1757 /* Parse the command arguements */
1760 printf ("Usage: %s <printer>\n", argv[0]);
1764 /* Get a printer handle */
1766 asprintf(&servername, "\\\\%s", cli->desthost);
1767 strupper_m(servername);
1768 asprintf(&printername, "%s\\%s", servername, argv[1]);
1770 werror = cli_spoolss_open_printer_ex(
1771 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1772 servername, cli->user_name, &handle);
1774 if (!W_ERROR_IS_OK(werror))
1779 /* Enumerate forms */
1781 werror = cli_spoolss_enumforms(
1782 cli, mem_ctx, 0, &needed, &handle, level, &num_forms, &forms);
1784 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1785 werror = cli_spoolss_enumforms(
1786 cli, mem_ctx, needed, NULL, &handle, level,
1787 &num_forms, &forms);
1789 if (!W_ERROR_IS_OK(werror))
1792 /* Display output */
1794 for (i = 0; i < num_forms; i++) {
1797 if (forms[i].name.buffer)
1798 rpcstr_pull(form_name, forms[i].name.buffer,
1799 sizeof(form_name), -1, STR_TERMINATE);
1801 printf("%s\n", form_name);
1806 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1808 SAFE_FREE(servername);
1809 SAFE_FREE(printername);
1814 static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
1815 TALLOC_CTX *mem_ctx,
1816 int argc, const char **argv)
1820 fstring servername, printername, user;
1822 BOOL opened_hnd = False;
1823 PRINTER_INFO_CTR ctr;
1824 PRINTER_INFO_0 info;
1825 REGISTRY_VALUE value;
1827 /* parse the command arguements */
1829 printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
1833 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1834 strupper_m(servername);
1835 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1836 fstrcpy(user, cli->user_name);
1838 /* get a printer handle */
1839 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1840 MAXIMUM_ALLOWED_ACCESS, servername,
1842 if (!W_ERROR_IS_OK(result))
1847 ctr.printers_0 = &info;
1849 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1852 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1853 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1855 if (!W_ERROR_IS_OK(result))
1858 printf("%s\n", timestring(True));
1859 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
1861 /* Set the printer data */
1863 fstrcpy(value.valuename, argv[2]);
1864 value.type = REG_SZ;
1865 value.size = strlen(argv[3]) + 1;
1866 value.data_p = talloc_memdup(mem_ctx, argv[3], value.size);
1868 result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
1870 if (!W_ERROR_IS_OK(result)) {
1871 printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
1874 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
1876 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, 0, &ctr);
1878 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1879 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1881 if (!W_ERROR_IS_OK(result))
1884 printf("%s\n", timestring(True));
1885 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
1890 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1895 static void display_job_info_1(JOB_INFO_1 *job)
1897 fstring username = "", document = "", text_status = "";
1899 rpcstr_pull(username, job->username.buffer,
1900 sizeof(username), -1, STR_TERMINATE);
1902 rpcstr_pull(document, job->document.buffer,
1903 sizeof(document), -1, STR_TERMINATE);
1905 rpcstr_pull(text_status, job->text_status.buffer,
1906 sizeof(text_status), -1, STR_TERMINATE);
1908 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
1909 username, document, text_status, job->pagesprinted,
1913 static void display_job_info_2(JOB_INFO_2 *job)
1915 fstring username = "", document = "", text_status = "";
1917 rpcstr_pull(username, job->username.buffer,
1918 sizeof(username), -1, STR_TERMINATE);
1920 rpcstr_pull(document, job->document.buffer,
1921 sizeof(document), -1, STR_TERMINATE);
1923 rpcstr_pull(text_status, job->text_status.buffer,
1924 sizeof(text_status), -1, STR_TERMINATE);
1926 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
1927 username, document, text_status, job->pagesprinted,
1928 job->totalpages, job->size);
1931 /* Enumerate jobs */
1933 static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
1934 TALLOC_CTX *mem_ctx, int argc,
1938 uint32 needed, level = 1, num_jobs, i;
1939 BOOL got_hnd = False;
1940 pstring printername;
1941 fstring servername, user;
1945 if (argc < 2 || argc > 3) {
1946 printf("Usage: %s printername [level]\n", argv[0]);
1951 level = atoi(argv[2]);
1953 /* Open printer handle */
1955 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1956 strupper_m(servername);
1957 fstrcpy(user, cli->user_name);
1958 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
1959 strupper_m(printername);
1960 pstrcat(printername, argv[1]);
1962 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
1963 "", MAXIMUM_ALLOWED_ACCESS,
1964 servername, user, &hnd);
1966 if (!W_ERROR_IS_OK(result))
1971 /* Enumerate ports */
1973 result = cli_spoolss_enumjobs(
1974 cli, mem_ctx, 0, &needed, &hnd, level, 0, 1000,
1977 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1978 result = cli_spoolss_enumjobs(
1979 cli, mem_ctx, needed, NULL, &hnd, level, 0,
1980 1000, &num_jobs, &ctr);
1982 if (!W_ERROR_IS_OK(result))
1985 for (i = 0; i < num_jobs; i++) {
1988 display_job_info_1(&ctr.job.job_info_1[i]);
1991 display_job_info_2(&ctr.job.job_info_2[i]);
1994 d_printf("unknown info level %d\n", level);
2001 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2006 /* enumerate data */
2008 static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
2009 TALLOC_CTX *mem_ctx, int argc,
2013 uint32 i=0, val_needed, data_needed;
2014 BOOL got_hnd = False;
2015 pstring printername;
2016 fstring servername, user;
2020 printf("Usage: %s printername\n", argv[0]);
2024 /* Open printer handle */
2026 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2027 strupper_m(servername);
2028 fstrcpy(user, cli->user_name);
2029 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2030 strupper_m(printername);
2031 pstrcat(printername, argv[1]);
2033 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2034 "", MAXIMUM_ALLOWED_ACCESS,
2035 servername, user, &hnd);
2037 if (!W_ERROR_IS_OK(result))
2042 /* Enumerate data */
2044 result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2045 &val_needed, &data_needed,
2047 while (W_ERROR_IS_OK(result)) {
2048 REGISTRY_VALUE value;
2049 result = cli_spoolss_enumprinterdata(
2050 cli, mem_ctx, &hnd, i++, val_needed,
2051 data_needed, 0, 0, &value);
2052 if (W_ERROR_IS_OK(result))
2053 display_reg_value(value);
2055 if (W_ERROR_V(result) == ERRnomoreitems)
2056 result = W_ERROR(ERRsuccess);
2060 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2065 /* enumerate data for a given key */
2067 static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
2068 TALLOC_CTX *mem_ctx, int argc,
2073 BOOL got_hnd = False;
2074 pstring printername;
2075 fstring servername, user;
2076 const char *keyname = NULL;
2081 printf("Usage: %s printername <keyname>\n", argv[0]);
2087 /* Open printer handle */
2089 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2090 strupper_m(servername);
2091 fstrcpy(user, cli->user_name);
2092 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2093 strupper_m(printername);
2094 pstrcat(printername, argv[1]);
2096 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2097 "", MAXIMUM_ALLOWED_ACCESS,
2098 servername, user, &hnd);
2100 if (!W_ERROR_IS_OK(result))
2105 /* Enumerate subkeys */
2107 result = cli_spoolss_enumprinterdataex(
2108 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL);
2110 if (W_ERROR_V(result) == ERRmoredata)
2111 result = cli_spoolss_enumprinterdataex(
2112 cli, mem_ctx, needed, NULL, &hnd, keyname, &ctr);
2114 if (!W_ERROR_IS_OK(result))
2117 for (i=0; i < ctr.num_values; i++) {
2118 display_reg_value(*(ctr.values[i]));
2121 regval_ctr_destroy(&ctr);
2125 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2130 /* enumerate subkeys */
2132 static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
2133 TALLOC_CTX *mem_ctx, int argc,
2137 uint32 needed, returned;
2138 BOOL got_hnd = False;
2139 pstring printername;
2140 fstring servername, user;
2141 const char *keyname = NULL;
2143 uint16 *keylist = NULL, *curkey;
2145 if (argc < 2 || argc > 3) {
2146 printf("Usage: %s printername [keyname]\n", argv[0]);
2155 /* Open printer handle */
2157 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2158 strupper_m(servername);
2159 fstrcpy(user, cli->user_name);
2160 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2161 strupper_m(printername);
2162 pstrcat(printername, argv[1]);
2164 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2165 "", MAXIMUM_ALLOWED_ACCESS,
2166 servername, user, &hnd);
2168 if (!W_ERROR_IS_OK(result))
2173 /* Enumerate subkeys */
2175 result = cli_spoolss_enumprinterkey(
2176 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL, NULL);
2178 if (W_ERROR_V(result) == ERRmoredata)
2179 result = cli_spoolss_enumprinterkey(
2180 cli, mem_ctx, needed, NULL, &hnd, keyname, &keylist,
2183 if (!W_ERROR_IS_OK(result))
2187 while (*curkey != 0) {
2189 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2191 printf("%s\n", subkey);
2192 curkey += strlen(subkey) + 1;
2199 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2204 static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
2205 TALLOC_CTX *mem_ctx, int argc,
2208 fstring servername, printername;
2210 BOOL got_hnd = False;
2212 SPOOL_NOTIFY_OPTION option;
2215 printf("Usage: %s printername\n", argv[0]);
2222 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2223 strupper_m(servername);
2225 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
2227 strupper_m(printername);
2229 result = cli_spoolss_open_printer_ex(
2230 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2231 servername, cli->user_name, &hnd);
2233 if (!W_ERROR_IS_OK(result)) {
2234 printf("Error opening %s\n", argv[1]);
2240 /* Create spool options */
2242 ZERO_STRUCT(option);
2245 option.option_type_ptr = 1;
2246 option.count = option.ctr.count = 2;
2248 option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc(
2249 mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2);
2251 ZERO_STRUCT(option.ctr.type[0]);
2252 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2253 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2254 option.ctr.type[0].fields_ptr = 1;
2255 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2257 ZERO_STRUCT(option.ctr.type[1]);
2258 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2259 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2260 option.ctr.type[1].fields_ptr = 1;
2261 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2265 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2266 strupper_m(servername);
2268 result = cli_spoolss_rffpcnex(
2269 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2271 if (!W_ERROR_IS_OK(result)) {
2272 printf("Error rffpcnex %s\n", argv[1]);
2278 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2283 /* List of commands exported by this module */
2284 struct cmd_set spoolss_commands[] = {
2288 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
2289 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
2290 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
2291 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
2292 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
2293 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
2294 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
2295 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
2296 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
2297 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
2298 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
2299 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
2300 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
2301 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
2302 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
2303 { "getprintprocdir",RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2304 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
2305 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
2306 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2307 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
2308 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
2309 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
2310 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
2311 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
2312 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
2313 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
2314 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },