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 },
44 /****************************************************************************
45 function to do the mapping between the long architecture name and
47 ****************************************************************************/
48 BOOL get_short_archi(char *short_archi, const char *long_archi)
52 DEBUG(107,("Getting architecture dependant directory\n"));
55 } while ( (archi_table[i].long_archi!=NULL ) &&
56 StrCaseCmp(long_archi, archi_table[i].long_archi) );
58 if (archi_table[i].long_archi==NULL) {
59 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
63 /* this might be client code - but shouldn't this be an fstrcpy etc? */
65 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
67 DEBUGADD(108,("index: [%d]\n", i));
68 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
69 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
75 /**********************************************************************
76 * dummy function -- placeholder
78 static NTSTATUS cmd_spoolss_not_implemented(struct cli_state *cli,
80 int argc, char **argv)
82 printf ("(*) This command is not currently implemented.\n");
87 /***********************************************************************
88 * Get printer information
90 static NTSTATUS cmd_spoolss_open_printer_ex(struct cli_state *cli,
92 int argc, char **argv)
96 fstring servername, user;
100 printf("Usage: %s <printername>\n", argv[0]);
105 return NT_STATUS_UNSUCCESSFUL;
107 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
108 strupper (servername);
109 fstrcpy (user, cli->user_name);
110 fstrcpy (printername, argv[1]);
112 /* Open the printer handle */
114 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
115 "", MAXIMUM_ALLOWED_ACCESS,
116 servername, user, &hnd);
118 if (W_ERROR_IS_OK(werror)) {
119 printf("Printer %s opened successfully\n", printername);
120 werror = cli_spoolss_close_printer(cli, mem_ctx, &hnd);
122 if (!W_ERROR_IS_OK(werror)) {
123 printf("Error closing printer handle! (%s)\n",
124 get_dos_error_msg(werror));
128 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
132 /****************************************************************************
133 printer info level 0 display function
134 ****************************************************************************/
135 static void display_print_info_0(PRINTER_INFO_0 *i0)
138 fstring servername = "";
143 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
145 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
147 printf("\tprintername:[%s]\n", name);
148 printf("\tservername:[%s]\n", servername);
149 printf("\tcjobs:[0x%x]\n", i0->cjobs);
150 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
152 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
153 i0->day, i0->dayofweek);
154 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
155 i0->second, i0->milliseconds);
157 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
158 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
160 printf("\tmajorversion:[0x%x]\n", i0->major_version);
161 printf("\tbuildversion:[0x%x]\n", i0->build_version);
163 printf("\tunknown7:[0x%x]\n", i0->unknown7);
164 printf("\tunknown8:[0x%x]\n", i0->unknown8);
165 printf("\tunknown9:[0x%x]\n", i0->unknown9);
166 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
167 printf("\tunknown11:[0x%x]\n", i0->unknown11);
168 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
169 printf("\tunknown13:[0x%x]\n", i0->unknown13);
170 printf("\tunknown14:[0x%x]\n", i0->unknown14);
171 printf("\tunknown15:[0x%x]\n", i0->unknown15);
172 printf("\tunknown16:[0x%x]\n", i0->unknown16);
173 printf("\tchange_id:[0x%x]\n", i0->change_id);
174 printf("\tunknown18:[0x%x]\n", i0->unknown18);
175 printf("\tstatus:[0x%x]\n", i0->status);
176 printf("\tunknown20:[0x%x]\n", i0->unknown20);
177 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
178 printf("\tunknown22:[0x%x]\n", i0->unknown22);
179 printf("\tunknown23:[0x%x]\n", i0->unknown23);
180 printf("\tunknown24:[0x%x]\n", i0->unknown24);
181 printf("\tunknown25:[0x%x]\n", i0->unknown25);
182 printf("\tunknown26:[0x%x]\n", i0->unknown26);
183 printf("\tunknown27:[0x%x]\n", i0->unknown27);
184 printf("\tunknown28:[0x%x]\n", i0->unknown28);
185 printf("\tunknown29:[0x%x]\n", i0->unknown29);
190 /****************************************************************************
191 printer info level 1 display function
192 ****************************************************************************/
193 static void display_print_info_1(PRINTER_INFO_1 *i1)
199 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
202 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
203 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
205 printf("\tflags:[0x%x]\n", i1->flags);
206 printf("\tname:[%s]\n", name);
207 printf("\tdescription:[%s]\n", desc);
208 printf("\tcomment:[%s]\n", comm);
213 /****************************************************************************
214 printer info level 2 display function
215 ****************************************************************************/
216 static void display_print_info_2(PRINTER_INFO_2 *i2)
218 fstring servername = "";
219 fstring printername = "";
220 fstring sharename = "";
221 fstring portname = "";
222 fstring drivername = "";
223 fstring comment = "";
224 fstring location = "";
225 fstring sepfile = "";
226 fstring printprocessor = "";
227 fstring datatype = "";
228 fstring parameters = "";
230 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
232 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
234 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
236 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
238 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
240 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
242 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
244 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
246 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
248 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
250 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
252 printf("\tservername:[%s]\n", servername);
253 printf("\tprintername:[%s]\n", printername);
254 printf("\tsharename:[%s]\n", sharename);
255 printf("\tportname:[%s]\n", portname);
256 printf("\tdrivername:[%s]\n", drivername);
257 printf("\tcomment:[%s]\n", comment);
258 printf("\tlocation:[%s]\n", location);
259 printf("\tsepfile:[%s]\n", sepfile);
260 printf("\tprintprocessor:[%s]\n", printprocessor);
261 printf("\tdatatype:[%s]\n", datatype);
262 printf("\tparameters:[%s]\n", parameters);
263 printf("\tattributes:[0x%x]\n", i2->attributes);
264 printf("\tpriority:[0x%x]\n", i2->priority);
265 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
266 printf("\tstarttime:[0x%x]\n", i2->starttime);
267 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
268 printf("\tstatus:[0x%x]\n", i2->status);
269 printf("\tcjobs:[0x%x]\n", i2->cjobs);
270 printf("\taverageppm:[0x%x]\n", i2->averageppm);
273 display_sec_desc(i2->secdesc);
278 /****************************************************************************
279 printer info level 3 display function
280 ****************************************************************************/
281 static void display_print_info_3(PRINTER_INFO_3 *i3)
283 printf("\tflags:[0x%x]\n", i3->flags);
285 display_sec_desc(i3->secdesc);
290 /* Enumerate printers */
292 static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli,
294 int argc, char **argv)
297 uint32 info_level = 1;
298 PRINTER_INFO_CTR ctr;
299 uint32 i = 0, num_printers, needed;
304 printf("Usage: %s [level] [name]\n", argv[0]);
309 info_level = atoi(argv[1]);
312 fstrcpy(name, argv[2]);
314 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
318 /* Enumerate printers -- Should we enumerate types other
319 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
323 result = cli_spoolss_enum_printers(
324 cli, mem_ctx, 0, &needed, name, PRINTER_ENUM_LOCAL,
325 info_level, &num_printers, &ctr);
327 if (W_ERROR_V(result) == ERRinsufficientbuffer)
328 result = cli_spoolss_enum_printers(
329 cli, mem_ctx, needed, NULL, name, PRINTER_ENUM_LOCAL,
330 info_level, &num_printers, &ctr);
332 if (W_ERROR_IS_OK(result)) {
335 printf ("No printers returned.\n");
339 for (i = 0; i < num_printers; i++) {
342 display_print_info_0(&ctr.printers_0[i]);
345 display_print_info_1(&ctr.printers_1[i]);
348 display_print_info_2(&ctr.printers_2[i]);
351 display_print_info_3(&ctr.printers_3[i]);
354 printf("unknown info level %d\n", info_level);
361 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
364 /****************************************************************************
365 port info level 1 display function
366 ****************************************************************************/
367 static void display_port_info_1(PORT_INFO_1 *i1)
371 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
372 printf("\tPort Name:\t[%s]\n", buffer);
375 /****************************************************************************
376 port info level 2 display function
377 ****************************************************************************/
378 static void display_port_info_2(PORT_INFO_2 *i2)
382 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
383 printf("\tPort Name:\t[%s]\n", buffer);
384 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
386 printf("\tMonitor Name:\t[%s]\n", buffer);
387 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
389 printf("\tDescription:\t[%s]\n", buffer);
390 printf("\tPort Type:\t[%d]\n", i2->port_type);
391 printf("\tReserved:\t[%d]\n", i2->reserved);
395 /* Enumerate ports */
397 static NTSTATUS cmd_spoolss_enum_ports(struct cli_state *cli,
398 TALLOC_CTX *mem_ctx, int argc,
402 uint32 needed, info_level = 1;
407 printf("Usage: %s [level]\n", argv[0]);
412 info_level = atoi(argv[1]);
414 /* Enumerate ports */
418 result = cli_spoolss_enum_ports(cli, mem_ctx, 0, &needed, info_level,
421 if (W_ERROR_V(result) == ERRinsufficientbuffer)
422 result = cli_spoolss_enum_ports(cli, mem_ctx, needed, NULL,
423 info_level, &returned, &ctr);
425 if (W_ERROR_IS_OK(result)) {
428 for (i = 0; i < returned; i++) {
429 switch (info_level) {
431 display_port_info_1(&ctr.port.info_1[i]);
434 display_port_info_2(&ctr.port.info_2[i]);
437 printf("unknown info level %d\n", info_level);
443 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
446 /***********************************************************************
447 * Set printer comment - use a level2 set.
449 static NTSTATUS cmd_spoolss_setprinter(struct cli_state *cli,
451 int argc, char **argv)
456 uint32 info_level = 2;
457 BOOL opened_hnd = False;
458 PRINTER_INFO_CTR ctr;
464 if (argc == 1 || argc > 3) {
465 printf("Usage: %s printername comment\n", argv[0]);
470 /* Open a printer handle */
472 fstrcpy(comment, argv[2]);
475 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
476 strupper (servername);
477 fstrcpy (printername, argv[1]);
478 fstrcpy (user, cli->user_name);
480 /* get a printer handle */
481 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
482 MAXIMUM_ALLOWED_ACCESS, servername,
485 if (!W_ERROR_IS_OK(result))
490 /* Get printer info */
491 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, info_level, &ctr);
493 if (W_ERROR_V(result) == ERRinsufficientbuffer)
494 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
496 if (!W_ERROR_IS_OK(result))
500 /* Modify the comment. */
501 init_unistr(&ctr.printers_2->comment, comment);
502 ctr.printers_2->devmode = NULL;
503 ctr.printers_2->secdesc = NULL;
505 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
506 if (W_ERROR_IS_OK(result))
507 printf("Success in setting comment.\n");
511 cli_spoolss_close_printer(cli, mem_ctx, &pol);
513 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
516 /***********************************************************************
517 * Get printer information
519 static NTSTATUS cmd_spoolss_getprinter(struct cli_state *cli,
521 int argc, char **argv)
525 uint32 info_level = 1;
526 BOOL opened_hnd = False;
527 PRINTER_INFO_CTR ctr;
533 if (argc == 1 || argc > 3) {
534 printf("Usage: %s <printername> [level]\n", argv[0]);
538 /* Open a printer handle */
540 info_level = atoi(argv[2]);
543 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
544 strupper (servername);
545 slprintf (printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
546 fstrcpy (user, cli->user_name);
548 /* get a printer handle */
550 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
551 "", MAXIMUM_ALLOWED_ACCESS,
552 servername, user, &pol);
554 if (!W_ERROR_IS_OK(result))
559 /* Get printer info */
561 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
562 &pol, info_level, &ctr);
564 if (W_ERROR_V(result) == ERRinsufficientbuffer)
565 result = cli_spoolss_getprinter(
566 cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
568 if (!W_ERROR_IS_OK(result))
571 /* Display printer info */
573 switch (info_level) {
575 display_print_info_0(ctr.printers_0);
578 display_print_info_1(ctr.printers_1);
581 display_print_info_2(ctr.printers_2);
584 display_print_info_3(ctr.printers_3);
587 printf("unknown info level %d\n", info_level);
593 cli_spoolss_close_printer(cli, mem_ctx, &pol);
595 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
598 static void display_reg_value(REGISTRY_VALUE value)
604 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
605 *((uint32 *) value.data_p));
608 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
610 printf("%s: REG_SZ: %s\n", value.valuename, text);
613 printf("%s: REG_BINARY: unknown length value not displayed\n",
617 uint16 *curstr = (uint16 *) value.data_p;
618 uint8 *start = value.data_p;
619 printf("%s: REG_MULTI_SZ:\n", value.valuename);
620 while ((*curstr != 0) &&
621 ((uint8 *) curstr < start + value.size)) {
622 rpcstr_pull(text, curstr, sizeof(text), -1,
624 printf(" %s\n", text);
625 curstr += strlen(text) + 1;
630 printf("%s: unknown type %d\n", value.valuename, value.type);
635 /***********************************************************************
638 static NTSTATUS cmd_spoolss_getprinterdata(struct cli_state *cli,
640 int argc, char **argv)
644 BOOL opened_hnd = False;
650 REGISTRY_VALUE value;
653 printf("Usage: %s <printername> <valuename>\n", argv[0]);
654 printf("<printername> of . queries print server\n");
659 /* Open a printer handle */
661 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
662 strupper (servername);
663 if (strncmp(argv[1], ".", sizeof(".")) == 0)
664 fstrcpy(printername, servername);
666 slprintf (printername, sizeof(servername)-1, "%s\\%s",
667 servername, argv[1]);
668 fstrcpy (user, cli->user_name);
670 /* get a printer handle */
672 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
673 "", MAXIMUM_ALLOWED_ACCESS,
674 servername, user, &pol);
676 if (!W_ERROR_IS_OK(result))
681 /* Get printer info */
683 result = cli_spoolss_getprinterdata(cli, mem_ctx, 0, &needed,
684 &pol, valuename, &value);
686 if (W_ERROR_V(result) == ERRmoredata)
687 result = cli_spoolss_getprinterdata(
688 cli, mem_ctx, needed, NULL, &pol, valuename, &value);
690 if (!W_ERROR_IS_OK(result))
693 /* Display printer data */
695 fstrcpy(value.valuename, valuename);
696 display_reg_value(value);
701 cli_spoolss_close_printer(cli, mem_ctx, &pol);
703 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
706 /***********************************************************************
709 static NTSTATUS cmd_spoolss_getprinterdataex(struct cli_state *cli,
711 int argc, char **argv)
715 BOOL opened_hnd = False;
720 char *valuename, *keyname;
721 REGISTRY_VALUE value;
724 printf("Usage: %s <printername> <keyname> <valuename>\n",
726 printf("<printername> of . queries print server\n");
732 /* Open a printer handle */
734 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
735 strupper (servername);
736 if (strncmp(argv[1], ".", sizeof(".")) == 0)
737 fstrcpy(printername, servername);
739 slprintf (printername, sizeof(printername)-1, "%s\\%s",
740 servername, argv[1]);
741 fstrcpy (user, cli->user_name);
743 /* get a printer handle */
745 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
746 "", MAXIMUM_ALLOWED_ACCESS,
747 servername, user, &pol);
749 if (!W_ERROR_IS_OK(result))
754 /* Get printer info */
756 result = cli_spoolss_getprinterdataex(cli, mem_ctx, 0, &needed,
757 &pol, keyname, valuename,
760 if (W_ERROR_V(result) == ERRmoredata)
761 result = cli_spoolss_getprinterdataex(cli, mem_ctx, needed,
765 if (!W_ERROR_IS_OK(result))
768 /* Display printer data */
770 fstrcpy(value.valuename, valuename);
771 display_reg_value(value);
776 cli_spoolss_close_printer(cli, mem_ctx, &pol);
778 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
781 /****************************************************************************
782 printer info level 0 display function
783 ****************************************************************************/
784 static void display_print_driver_1(DRIVER_INFO_1 *i1)
790 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
792 printf ("Printer Driver Info 1:\n");
793 printf ("\tDriver Name: [%s]\n\n", name);
798 /****************************************************************************
799 printer info level 1 display function
800 ****************************************************************************/
801 static void display_print_driver_2(DRIVER_INFO_2 *i1)
804 fstring architecture;
811 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
812 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
813 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
814 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
815 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
817 printf ("Printer Driver Info 2:\n");
818 printf ("\tVersion: [%x]\n", i1->version);
819 printf ("\tDriver Name: [%s]\n", name);
820 printf ("\tArchitecture: [%s]\n", architecture);
821 printf ("\tDriver Path: [%s]\n", driverpath);
822 printf ("\tDatafile: [%s]\n", datafile);
823 printf ("\tConfigfile: [%s]\n\n", configfile);
828 /****************************************************************************
829 printer info level 2 display function
830 ****************************************************************************/
831 static void display_print_driver_3(DRIVER_INFO_3 *i1)
834 fstring architecture = "";
835 fstring driverpath = "";
836 fstring datafile = "";
837 fstring configfile = "";
838 fstring helpfile = "";
839 fstring dependentfiles = "";
840 fstring monitorname = "";
841 fstring defaultdatatype = "";
849 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
850 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
851 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
852 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
853 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
854 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
855 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
856 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
858 printf ("Printer Driver Info 3:\n");
859 printf ("\tVersion: [%x]\n", i1->version);
860 printf ("\tDriver Name: [%s]\n",name);
861 printf ("\tArchitecture: [%s]\n", architecture);
862 printf ("\tDriver Path: [%s]\n", driverpath);
863 printf ("\tDatafile: [%s]\n", datafile);
864 printf ("\tConfigfile: [%s]\n", configfile);
865 printf ("\tHelpfile: [%s]\n\n", helpfile);
869 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
871 length+=strlen(dependentfiles)+1;
873 if (strlen(dependentfiles) > 0)
875 printf ("\tDependentfiles: [%s]\n", dependentfiles);
885 printf ("\tMonitorname: [%s]\n", monitorname);
886 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
891 /***********************************************************************
892 * Get printer information
894 static NTSTATUS cmd_spoolss_getdriver(struct cli_state *cli,
896 int argc, char **argv)
901 uint32 info_level = 3;
902 BOOL opened_hnd = False;
903 PRINTER_DRIVER_CTR ctr;
909 if ((argc == 1) || (argc > 3))
911 printf("Usage: %s <printername> [level]\n", argv[0]);
915 /* get the arguments need to open the printer handle */
916 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
917 strupper (servername);
918 fstrcpy (user, cli->user_name);
919 fstrcpy (printername, argv[1]);
921 info_level = atoi(argv[2]);
923 /* Open a printer handle */
925 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
927 servername, user, &pol);
929 result = W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
931 if (!NT_STATUS_IS_OK(result)) {
932 printf("Error opening printer handle for %s!\n", printername);
938 /* loop through and print driver info level for each architecture */
940 for (i=0; archi_table[i].long_archi!=NULL; i++) {
943 werror = cli_spoolss_getprinterdriver(
944 cli, mem_ctx, 0, &needed, &pol, info_level,
945 archi_table[i].long_archi, &ctr);
947 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
948 werror = cli_spoolss_getprinterdriver(
949 cli, mem_ctx, needed, NULL, &pol, info_level,
950 archi_table[i].long_archi, &ctr);
952 if (!W_ERROR_IS_OK(werror))
955 printf ("\n[%s]\n", archi_table[i].long_archi);
957 switch (info_level) {
959 display_print_driver_1 (ctr.info1);
962 display_print_driver_2 (ctr.info2);
965 display_print_driver_3 (ctr.info3);
968 printf("unknown info level %d\n", info_level);
976 cli_spoolss_close_printer (cli, mem_ctx, &pol);
978 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
981 /***********************************************************************
982 * Get printer information
984 static NTSTATUS cmd_spoolss_enum_drivers(struct cli_state *cli,
986 int argc, char **argv)
989 uint32 info_level = 1;
990 PRINTER_DRIVER_CTR ctr;
996 printf("Usage: enumdrivers [level]\n");
1001 info_level = atoi(argv[1]);
1004 /* loop through and print driver info level for each architecture */
1005 for (i=0; archi_table[i].long_archi!=NULL; i++)
1009 werror = cli_spoolss_enumprinterdrivers(
1010 cli, mem_ctx, 0, &needed, info_level,
1011 archi_table[i].long_archi, &returned, &ctr);
1013 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1014 werror = cli_spoolss_enumprinterdrivers(
1015 cli, mem_ctx, needed, NULL, info_level,
1016 archi_table[i].long_archi, &returned, &ctr);
1021 if (!W_ERROR_IS_OK(werror)) {
1022 printf ("Error getting driver for environment [%s] - %d\n",
1023 archi_table[i].long_archi, W_ERROR_V(werror));
1027 printf ("\n[%s]\n", archi_table[i].long_archi);
1032 for (j=0; j < returned; j++) {
1033 display_print_driver_1 (&(ctr.info1[j]));
1037 for (j=0; j < returned; j++) {
1038 display_print_driver_2 (&(ctr.info2[j]));
1042 for (j=0; j < returned; j++) {
1043 display_print_driver_3 (&(ctr.info3[j]));
1047 printf("unknown info level %d\n", info_level);
1052 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1055 /****************************************************************************
1056 printer info level 1 display function
1057 ****************************************************************************/
1058 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1064 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1066 printf ("\tDirectory Name:[%s]\n", name);
1069 /***********************************************************************
1070 * Get printer driver directory information
1072 static NTSTATUS cmd_spoolss_getdriverdir(struct cli_state *cli,
1073 TALLOC_CTX *mem_ctx,
1074 int argc, char **argv)
1078 DRIVER_DIRECTORY_CTR ctr;
1082 printf("Usage: %s [environment]\n", argv[0]);
1083 return NT_STATUS_OK;
1086 /* Get the arguments need to open the printer handle */
1089 fstrcpy (env, argv[1]);
1091 fstrcpy (env, "Windows NT x86");
1093 /* Get the directory. Only use Info level 1 */
1095 result = cli_spoolss_getprinterdriverdir(
1096 cli, mem_ctx, 0, &needed, 1, env, &ctr);
1098 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1099 result = cli_spoolss_getprinterdriverdir(
1100 cli, mem_ctx, needed, NULL, 1, env, &ctr);
1102 if (W_ERROR_IS_OK(result))
1103 display_printdriverdir_1(ctr.info1);
1105 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1108 /*******************************************************************************
1109 set the version and environment fields of a DRIVER_INFO_3 struct
1110 ******************************************************************************/
1111 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1116 for (i=0; archi_table[i].long_archi != NULL; i++)
1118 if (strcmp(arch, archi_table[i].short_archi) == 0)
1120 info->version = archi_table[i].version;
1121 init_unistr (&info->architecture, archi_table[i].long_archi);
1126 if (archi_table[i].long_archi == NULL)
1128 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1135 /**************************************************************************
1136 wrapper for strtok to get the next parameter from a delimited list.
1137 Needed to handle the empty parameter string denoted by "NULL"
1138 *************************************************************************/
1139 static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
1143 /* get the next token */
1144 ptr = strtok(str, delim);
1146 /* a string of 'NULL' is used to represent an empty
1147 parameter because two consecutive delimiters
1148 will not return an empty string. See man strtok(3)
1150 if (StrCaseCmp(ptr, "NULL") == 0)
1154 init_unistr(dest, ptr);
1159 /********************************************************************************
1160 fill in the members of a DRIVER_INFO_3 struct using a character
1161 string in the form of
1162 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1163 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1164 <Default Data Type>:<Comma Separated list of Files>
1165 *******************************************************************************/
1166 static BOOL init_drv_info_3_members (
1167 TALLOC_CTX *mem_ctx,
1168 DRIVER_INFO_3 *info,
1175 /* fill in the UNISTR fields */
1176 str = get_driver_3_param (args, ":", &info->name);
1177 str = get_driver_3_param (NULL, ":", &info->driverpath);
1178 str = get_driver_3_param (NULL, ":", &info->datafile);
1179 str = get_driver_3_param (NULL, ":", &info->configfile);
1180 str = get_driver_3_param (NULL, ":", &info->helpfile);
1181 str = get_driver_3_param (NULL, ":", &info->monitorname);
1182 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1184 /* <Comma Separated List of Dependent Files> */
1185 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1188 /* begin to strip out each filename */
1189 str = strtok(str, ",");
1193 /* keep a cumlative count of the str lengths */
1194 len += strlen(str)+1;
1195 str = strtok(NULL, ",");
1198 /* allocate the space; add one extra slot for a terminating NULL.
1199 Each filename is NULL terminated and the end contains a double
1201 if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL)
1203 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1206 for (i=0; i<len; i++)
1208 info->dependentfiles[i] = SSVAL(&info->dependentfiles[i], 0, str2[i]);
1210 info->dependentfiles[len] = '\0';
1216 static NTSTATUS cmd_spoolss_addprinterdriver(struct cli_state *cli,
1217 TALLOC_CTX *mem_ctx,
1218 int argc, char **argv)
1222 PRINTER_DRIVER_CTR ctr;
1223 DRIVER_INFO_3 info3;
1225 fstring driver_name;
1227 /* parse the command arguements */
1230 printf ("Usage: %s <Environment>\\\n", argv[0]);
1231 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1232 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1233 printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
1235 return NT_STATUS_OK;
1238 /* Fill in the DRIVER_INFO_3 struct */
1240 if (!get_short_archi(arch, argv[1]))
1242 printf ("Error Unknown architechture [%s]\n", argv[1]);
1243 return NT_STATUS_INVALID_PARAMETER;
1246 set_drv_info_3_env(&info3, arch);
1248 if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
1250 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1251 return NT_STATUS_INVALID_PARAMETER;
1256 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1258 if (W_ERROR_IS_OK(result)) {
1259 rpcstr_pull(driver_name, info3.name.buffer,
1260 sizeof(driver_name), -1, STR_TERMINATE);
1261 printf ("Printer Driver %s successfully installed.\n",
1265 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1269 static NTSTATUS cmd_spoolss_addprinterex(struct cli_state *cli,
1270 TALLOC_CTX *mem_ctx,
1271 int argc, char **argv)
1275 PRINTER_INFO_CTR ctr;
1276 PRINTER_INFO_2 info2;
1279 /* parse the command arguements */
1282 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1283 return NT_STATUS_OK;
1286 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1287 strupper (servername);
1289 /* Fill in the DRIVER_INFO_3 struct */
1292 init_unistr( &info2.servername, servername);
1294 init_unistr( &info2.printername, argv[1]);
1295 init_unistr( &info2.sharename, argv[2]);
1296 init_unistr( &info2.drivername, argv[3]);
1297 init_unistr( &info2.portname, argv[4]);
1298 init_unistr( &info2.comment, "Created by rpcclient");
1299 init_unistr( &info2.printprocessor, "winprint");
1300 init_unistr( &info2.datatype, "RAW");
1301 info2.devmode = NULL;
1302 info2.secdesc = NULL;
1303 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1305 info2.defaultpriority = 0;
1306 info2.starttime = 0;
1307 info2.untiltime = 0;
1309 /* These three fields must not be used by AddPrinter()
1310 as defined in the MS Platform SDK documentation..
1314 info2.averageppm = 0;
1317 ctr.printers_2 = &info2;
1318 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1320 if (W_ERROR_IS_OK(result))
1321 printf ("Printer %s successfully installed.\n", argv[1]);
1323 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1326 static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli,
1327 TALLOC_CTX *mem_ctx,
1328 int argc, char **argv)
1333 BOOL opened_hnd = False;
1334 PRINTER_INFO_CTR ctr;
1335 PRINTER_INFO_2 info2;
1341 /* parse the command arguements */
1344 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1345 return NT_STATUS_OK;
1348 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1349 strupper (servername);
1350 slprintf (printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1351 fstrcpy (user, cli->user_name);
1353 /* Get a printer handle */
1355 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1356 MAXIMUM_ALLOWED_ACCESS,
1357 servername, user, &pol);
1359 if (!W_ERROR_IS_OK(result))
1364 /* Get printer info */
1366 ZERO_STRUCT (info2);
1367 ctr.printers_2 = &info2;
1369 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1372 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1373 result = cli_spoolss_getprinter(
1374 cli, mem_ctx, needed, NULL, &pol, level, &ctr);
1376 if (!W_ERROR_IS_OK(result)) {
1377 printf ("Unable to retrieve printer information!\n");
1381 /* Set the printer driver */
1383 init_unistr(&ctr.printers_2->drivername, argv[2]);
1385 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1387 if (!W_ERROR_IS_OK(result)) {
1388 printf("SetPrinter call failed!\n");
1392 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1398 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1400 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1404 static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli,
1405 TALLOC_CTX *mem_ctx,
1406 int argc, char **argv)
1412 /* parse the command arguements */
1415 printf ("Usage: %s <driver>\n", argv[0]);
1416 return NT_STATUS_OK;
1419 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1420 strupper (servername);
1422 /* delete the driver for all architectures */
1423 for (i=0; archi_table[i].long_archi; i++)
1425 /* make the call to remove the driver */
1426 result = cli_spoolss_deleteprinterdriver(
1427 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1429 if ( !W_ERROR_IS_OK(result) ) {
1430 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1431 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1432 argv[1], archi_table[i].long_archi,
1438 printf ("Driver %s removed for arch [%s].\n", argv[1],
1439 archi_table[i].long_archi);
1443 return W_ERROR_IS_OK(result) || W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1446 static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli,
1447 TALLOC_CTX *mem_ctx,
1448 int argc, char **argv)
1451 char *servername = NULL, *environment = NULL;
1455 /* parse the command arguements */
1457 printf ("Usage: %s [environment]\n", argv[0]);
1458 return NT_STATUS_OK;
1461 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1462 return NT_STATUS_NO_MEMORY;
1463 strupper(servername);
1465 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1466 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1467 SAFE_FREE(servername);
1468 return NT_STATUS_NO_MEMORY;
1471 result = cli_spoolss_getprintprocessordirectory(
1472 cli, mem_ctx, 0, &needed, servername, environment, procdir);
1474 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1475 result = cli_spoolss_getprintprocessordirectory(
1476 cli, mem_ctx, needed, NULL, servername, environment,
1479 if (W_ERROR_IS_OK(result))
1480 printf("%s\n", procdir);
1482 SAFE_FREE(servername);
1483 SAFE_FREE(environment);
1485 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1490 static NTSTATUS cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1491 int argc, char **argv)
1495 char *servername = NULL, *printername = NULL;
1497 BOOL got_handle = False;
1499 /* Parse the command arguements */
1502 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1503 return NT_STATUS_OK;
1506 /* Get a printer handle */
1508 asprintf(&servername, "\\\\%s", cli->desthost);
1509 strupper(servername);
1510 asprintf(&printername, "%s\\%s", servername, argv[1]);
1512 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1513 MAXIMUM_ALLOWED_ACCESS,
1514 servername, cli->user_name, &handle);
1516 if (!W_ERROR_IS_OK(werror))
1521 /* Dummy up some values for the form data */
1523 form.flags = FORM_USER;
1524 form.size_x = form.size_y = 100;
1530 init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
1535 werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1539 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1541 SAFE_FREE(servername);
1542 SAFE_FREE(printername);
1544 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1549 static NTSTATUS cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1550 int argc, char **argv)
1554 char *servername = NULL, *printername = NULL;
1556 BOOL got_handle = False;
1558 /* Parse the command arguements */
1561 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1562 return NT_STATUS_OK;
1565 /* Get a printer handle */
1567 asprintf(&servername, "\\\\%s", cli->desthost);
1568 strupper(servername);
1569 asprintf(&printername, "%s\\%s", servername, argv[1]);
1571 werror = cli_spoolss_open_printer_ex(
1572 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1573 servername, cli->user_name, &handle);
1575 if (!W_ERROR_IS_OK(werror))
1580 /* Dummy up some values for the form data */
1582 form.flags = FORM_PRINTER;
1583 form.size_x = form.size_y = 100;
1589 init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
1593 werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1597 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1599 SAFE_FREE(servername);
1600 SAFE_FREE(printername);
1602 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1607 static NTSTATUS cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1608 int argc, char **argv)
1612 char *servername = NULL, *printername = NULL;
1614 BOOL got_handle = False;
1617 /* Parse the command arguements */
1620 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1621 return NT_STATUS_OK;
1624 /* Get a printer handle */
1626 asprintf(&servername, "\\\\%s", cli->desthost);
1627 strupper(servername);
1628 asprintf(&printername, "%s\\%s", servername, argv[1]);
1630 werror = cli_spoolss_open_printer_ex(
1631 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1632 servername, cli->user_name, &handle);
1634 if (!W_ERROR_IS_OK(werror))
1641 werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
1642 &handle, argv[2], 1, &form);
1644 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1645 werror = cli_spoolss_getform(cli, mem_ctx, needed, NULL,
1646 &handle, argv[2], 1, &form);
1648 if (!W_ERROR_IS_OK(werror))
1651 printf("width: %d\n", form.width);
1652 printf("length: %d\n", form.length);
1653 printf("left: %d\n", form.left);
1654 printf("top: %d\n", form.top);
1655 printf("right: %d\n", form.right);
1656 printf("bottom: %d\n", form.bottom);
1660 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1662 SAFE_FREE(servername);
1663 SAFE_FREE(printername);
1665 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1670 static NTSTATUS cmd_spoolss_deleteform(struct cli_state *cli,
1671 TALLOC_CTX *mem_ctx, int argc,
1676 char *servername = NULL, *printername = NULL;
1677 BOOL got_handle = False;
1679 /* Parse the command arguements */
1682 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1683 return NT_STATUS_OK;
1686 /* Get a printer handle */
1688 asprintf(&servername, "\\\\%s", cli->desthost);
1689 strupper(servername);
1690 asprintf(&printername, "%s\\%s", servername, argv[1]);
1692 werror = cli_spoolss_open_printer_ex(
1693 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1694 servername, cli->user_name, &handle);
1696 if (!W_ERROR_IS_OK(werror))
1701 /* Delete the form */
1703 werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1707 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1709 SAFE_FREE(servername);
1710 SAFE_FREE(printername);
1712 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1715 /* Enumerate forms */
1717 static NTSTATUS cmd_spoolss_enum_forms(struct cli_state *cli,
1718 TALLOC_CTX *mem_ctx, int argc,
1723 char *servername = NULL, *printername = NULL;
1724 BOOL got_handle = False;
1725 uint32 needed, num_forms, level = 1, i;
1728 /* Parse the command arguements */
1731 printf ("Usage: %s <printer>\n", argv[0]);
1732 return NT_STATUS_OK;
1735 /* Get a printer handle */
1737 asprintf(&servername, "\\\\%s", cli->desthost);
1738 strupper(servername);
1739 asprintf(&printername, "%s\\%s", servername, argv[1]);
1741 werror = cli_spoolss_open_printer_ex(
1742 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1743 servername, cli->user_name, &handle);
1745 if (!W_ERROR_IS_OK(werror))
1750 /* Enumerate forms */
1752 werror = cli_spoolss_enumforms(
1753 cli, mem_ctx, 0, &needed, &handle, level, &num_forms, &forms);
1755 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1756 werror = cli_spoolss_enumforms(
1757 cli, mem_ctx, needed, NULL, &handle, level,
1758 &num_forms, &forms);
1760 if (!W_ERROR_IS_OK(werror))
1763 /* Display output */
1765 for (i = 0; i < num_forms; i++) {
1768 if (forms[i].name.buffer)
1769 rpcstr_pull(form_name, forms[i].name.buffer,
1770 sizeof(form_name), -1, STR_TERMINATE);
1772 printf("%s\n", form_name);
1777 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1779 SAFE_FREE(servername);
1780 SAFE_FREE(printername);
1782 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1785 static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli,
1786 TALLOC_CTX *mem_ctx,
1787 int argc, char **argv)
1791 fstring servername, printername, user;
1793 BOOL opened_hnd = False;
1794 PRINTER_INFO_CTR ctr;
1795 PRINTER_INFO_0 info;
1796 REGISTRY_VALUE value;
1798 /* parse the command arguements */
1800 printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
1801 return NT_STATUS_OK;
1804 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1805 strupper (servername);
1806 slprintf (printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1807 fstrcpy (user, cli->user_name);
1809 /* get a printer handle */
1810 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1811 MAXIMUM_ALLOWED_ACCESS, servername,
1813 if (!W_ERROR_IS_OK(result))
1818 ctr.printers_0 = &info;
1820 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1823 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1824 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1826 if (!W_ERROR_IS_OK(result))
1829 printf("%s\n", timestring(True));
1830 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
1832 /* Set the printer data */
1834 fstrcpy(value.valuename, argv[2]);
1835 value.type = REG_SZ;
1836 value.size = strlen(argv[3]) + 1;
1837 value.data_p = talloc_memdup(mem_ctx, argv[3], value.size);
1839 result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
1841 if (!W_ERROR_IS_OK(result)) {
1842 printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
1845 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
1847 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, 0, &ctr);
1849 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1850 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1852 if (!W_ERROR_IS_OK(result))
1855 printf("%s\n", timestring(True));
1856 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
1861 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1863 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1866 static void display_job_info_1(JOB_INFO_1 *job)
1868 fstring username = "", document = "", text_status = "";
1870 rpcstr_pull(username, job->username.buffer,
1871 sizeof(username), -1, STR_TERMINATE);
1873 rpcstr_pull(document, job->document.buffer,
1874 sizeof(document), -1, STR_TERMINATE);
1876 rpcstr_pull(text_status, job->text_status.buffer,
1877 sizeof(text_status), -1, STR_TERMINATE);
1879 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
1880 username, document, text_status, job->pagesprinted,
1884 static void display_job_info_2(JOB_INFO_2 *job)
1886 fstring username = "", document = "", text_status = "";
1888 rpcstr_pull(username, job->username.buffer,
1889 sizeof(username), -1, STR_TERMINATE);
1891 rpcstr_pull(document, job->document.buffer,
1892 sizeof(document), -1, STR_TERMINATE);
1894 rpcstr_pull(text_status, job->text_status.buffer,
1895 sizeof(text_status), -1, STR_TERMINATE);
1897 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
1898 username, document, text_status, job->pagesprinted,
1899 job->totalpages, job->size);
1902 /* Enumerate jobs */
1904 static NTSTATUS cmd_spoolss_enum_jobs(struct cli_state *cli,
1905 TALLOC_CTX *mem_ctx, int argc,
1909 uint32 needed, level = 1, num_jobs, i;
1910 BOOL got_hnd = False;
1911 pstring printername;
1912 fstring servername, user;
1916 if (argc < 2 || argc > 3) {
1917 printf("Usage: %s printername [level]\n", argv[0]);
1918 return NT_STATUS_OK;
1922 level = atoi(argv[2]);
1924 /* Open printer handle */
1926 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1927 strupper(servername);
1928 fstrcpy(user, cli->user_name);
1929 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
1930 strupper(printername);
1931 pstrcat(printername, argv[1]);
1933 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
1934 "", MAXIMUM_ALLOWED_ACCESS,
1935 servername, user, &hnd);
1937 if (!W_ERROR_IS_OK(result))
1942 /* Enumerate ports */
1944 result = cli_spoolss_enumjobs(
1945 cli, mem_ctx, 0, &needed, &hnd, level, 0, 1000,
1948 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1949 result = cli_spoolss_enumjobs(
1950 cli, mem_ctx, needed, NULL, &hnd, level, 0,
1951 1000, &num_jobs, &ctr);
1953 if (!W_ERROR_IS_OK(result))
1956 for (i = 0; i < num_jobs; i++) {
1959 display_job_info_1(&ctr.job.job_info_1[i]);
1962 display_job_info_2(&ctr.job.job_info_2[i]);
1965 d_printf("unknown info level %d\n", level);
1972 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
1974 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1977 /* enumerate data */
1979 static NTSTATUS cmd_spoolss_enum_data( struct cli_state *cli,
1980 TALLOC_CTX *mem_ctx, int argc,
1984 uint32 i=0, val_needed, data_needed;
1985 BOOL got_hnd = False;
1986 pstring printername;
1987 fstring servername, user;
1991 printf("Usage: %s printername\n", argv[0]);
1992 return NT_STATUS_OK;
1995 /* Open printer handle */
1997 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1998 strupper(servername);
1999 fstrcpy(user, cli->user_name);
2000 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2001 strupper(printername);
2002 pstrcat(printername, argv[1]);
2004 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2005 "", MAXIMUM_ALLOWED_ACCESS,
2006 servername, user, &hnd);
2008 if (!W_ERROR_IS_OK(result))
2013 /* Enumerate data */
2015 result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2016 &val_needed, &data_needed,
2018 while (W_ERROR_IS_OK(result)) {
2019 REGISTRY_VALUE value;
2020 result = cli_spoolss_enumprinterdata(
2021 cli, mem_ctx, &hnd, i++, val_needed,
2022 data_needed, 0, 0, &value);
2023 if (W_ERROR_IS_OK(result))
2024 display_reg_value(value);
2026 if (W_ERROR_V(result) == ERRnomoreitems)
2027 result = W_ERROR(ERRsuccess);
2031 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2033 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2036 /* enumerate data for a given key */
2038 static NTSTATUS cmd_spoolss_enum_data_ex( struct cli_state *cli,
2039 TALLOC_CTX *mem_ctx, int argc,
2044 BOOL got_hnd = False;
2045 pstring printername;
2046 fstring servername, user;
2047 char *keyname = NULL;
2052 printf("Usage: %s printername <keyname>\n", argv[0]);
2053 return NT_STATUS_OK;
2058 /* Open printer handle */
2060 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2061 strupper(servername);
2062 fstrcpy(user, cli->user_name);
2063 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2064 strupper(printername);
2065 pstrcat(printername, argv[1]);
2067 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2068 "", MAXIMUM_ALLOWED_ACCESS,
2069 servername, user, &hnd);
2071 if (!W_ERROR_IS_OK(result))
2076 /* Enumerate subkeys */
2078 result = cli_spoolss_enumprinterdataex(
2079 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL);
2081 if (W_ERROR_V(result) == ERRmoredata)
2082 result = cli_spoolss_enumprinterdataex(
2083 cli, mem_ctx, needed, NULL, &hnd, keyname, &ctr);
2085 if (!W_ERROR_IS_OK(result))
2088 for (i=0; i < ctr.num_values; i++) {
2089 display_reg_value(*(ctr.values[i]));
2092 regval_ctr_destroy(&ctr);
2096 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2098 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2101 /* enumerate subkeys */
2103 static NTSTATUS cmd_spoolss_enum_printerkey( struct cli_state *cli,
2104 TALLOC_CTX *mem_ctx, int argc,
2108 uint32 needed, returned;
2109 BOOL got_hnd = False;
2110 pstring printername;
2111 fstring servername, user;
2112 const char *keyname = NULL;
2114 uint16 *keylist = NULL, *curkey;
2116 if (argc < 2 || argc > 3) {
2117 printf("Usage: %s printername [keyname]\n", argv[0]);
2118 return NT_STATUS_OK;
2126 /* Open printer handle */
2128 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2129 strupper(servername);
2130 fstrcpy(user, cli->user_name);
2131 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2132 strupper(printername);
2133 pstrcat(printername, argv[1]);
2135 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2136 "", MAXIMUM_ALLOWED_ACCESS,
2137 servername, user, &hnd);
2139 if (!W_ERROR_IS_OK(result))
2144 /* Enumerate subkeys */
2146 result = cli_spoolss_enumprinterkey(
2147 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL, NULL);
2149 if (W_ERROR_V(result) == ERRmoredata)
2150 result = cli_spoolss_enumprinterkey(
2151 cli, mem_ctx, needed, NULL, &hnd, keyname, &keylist,
2154 if (!W_ERROR_IS_OK(result))
2158 while (*curkey != 0) {
2160 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2162 printf("%s\n", subkey);
2163 curkey += strlen(subkey) + 1;
2170 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2172 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2175 static NTSTATUS cmd_spoolss_rffpcnex(struct cli_state *cli,
2176 TALLOC_CTX *mem_ctx, int argc,
2179 fstring servername, printername;
2181 BOOL got_hnd = False;
2183 SPOOL_NOTIFY_OPTION option;
2186 printf("Usage: %s printername\n", argv[0]);
2193 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2194 strupper(servername);
2196 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
2198 strupper(printername);
2200 result = cli_spoolss_open_printer_ex(
2201 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2202 servername, cli->user_name, &hnd);
2204 if (!W_ERROR_IS_OK(result)) {
2205 printf("Error opening %s\n", argv[1]);
2211 /* Create spool options */
2213 ZERO_STRUCT(option);
2216 option.option_type_ptr = 1;
2217 option.count = option.ctr.count = 2;
2219 option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc(
2220 mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2);
2222 ZERO_STRUCT(option.ctr.type[0]);
2223 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2224 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2225 option.ctr.type[0].fields_ptr = 1;
2226 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2228 ZERO_STRUCT(option.ctr.type[1]);
2229 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2230 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2231 option.ctr.type[1].fields_ptr = 1;
2232 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2236 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2237 strupper(servername);
2239 result = cli_spoolss_rffpcnex(
2240 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2242 if (!W_ERROR_IS_OK(result)) {
2243 printf("Error rffpcnex %s\n", argv[1]);
2249 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2251 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2254 /* List of commands exported by this module */
2255 struct cmd_set spoolss_commands[] = {
2259 { "adddriver", cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
2260 { "addprinter", cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
2261 { "deldriver", cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
2262 { "enumdata", cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
2263 { "enumdataex", cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
2264 { "enumkey", cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
2265 { "enumjobs", cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
2266 { "enumports", cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
2267 { "enumdrivers", cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
2268 { "enumprinters", cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
2269 { "getdata", cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
2270 { "getdataex", cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
2271 { "getdriver", cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
2272 { "getdriverdir", cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
2273 { "getprinter", cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
2274 { "getprintprocdir", cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2275 { "openprinter", cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
2276 { "setdriver", cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
2277 { "getprintprocdir", cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2278 { "addform", cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
2279 { "setform", cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
2280 { "getform", cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
2281 { "deleteform", cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
2282 { "enumforms", cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
2283 { "setprinter", cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
2284 { "setprinterdata", cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
2285 { "rffpcnex", cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },