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 BOOL get_short_archi(char *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? */
74 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
76 DEBUGADD(108,("index: [%d]\n", i));
77 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
78 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
84 /**********************************************************************
85 * dummy function -- placeholder
87 static NTSTATUS cmd_spoolss_not_implemented(struct cli_state *cli,
89 int argc, const char **argv)
91 printf ("(*) This command is not currently implemented.\n");
96 /***********************************************************************
97 * Get printer information
99 static NTSTATUS cmd_spoolss_open_printer_ex(struct cli_state *cli,
101 int argc, const char **argv)
105 fstring servername, user;
109 printf("Usage: %s <printername>\n", argv[0]);
114 return NT_STATUS_UNSUCCESSFUL;
116 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
117 strupper (servername);
118 fstrcpy (user, cli->user_name);
119 fstrcpy (printername, argv[1]);
121 /* Open the printer handle */
123 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
124 "", PRINTER_ALL_ACCESS,
125 servername, user, &hnd);
127 if (W_ERROR_IS_OK(werror)) {
128 printf("Printer %s opened successfully\n", printername);
129 werror = cli_spoolss_close_printer(cli, mem_ctx, &hnd);
131 if (!W_ERROR_IS_OK(werror)) {
132 printf("Error closing printer handle! (%s)\n",
133 get_dos_error_msg(werror));
137 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
141 /****************************************************************************
142 printer info level 0 display function
143 ****************************************************************************/
144 static void display_print_info_0(PRINTER_INFO_0 *i0)
147 fstring servername = "";
152 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
154 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
156 printf("\tprintername:[%s]\n", name);
157 printf("\tservername:[%s]\n", servername);
158 printf("\tcjobs:[0x%x]\n", i0->cjobs);
159 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
161 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
162 i0->day, i0->dayofweek);
163 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
164 i0->second, i0->milliseconds);
166 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
167 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
169 printf("\tmajorversion:[0x%x]\n", i0->major_version);
170 printf("\tbuildversion:[0x%x]\n", i0->build_version);
172 printf("\tunknown7:[0x%x]\n", i0->unknown7);
173 printf("\tunknown8:[0x%x]\n", i0->unknown8);
174 printf("\tunknown9:[0x%x]\n", i0->unknown9);
175 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
176 printf("\tunknown11:[0x%x]\n", i0->unknown11);
177 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
178 printf("\tunknown13:[0x%x]\n", i0->unknown13);
179 printf("\tunknown14:[0x%x]\n", i0->unknown14);
180 printf("\tunknown15:[0x%x]\n", i0->unknown15);
181 printf("\tunknown16:[0x%x]\n", i0->unknown16);
182 printf("\tchange_id:[0x%x]\n", i0->change_id);
183 printf("\tunknown18:[0x%x]\n", i0->unknown18);
184 printf("\tstatus:[0x%x]\n", i0->status);
185 printf("\tunknown20:[0x%x]\n", i0->unknown20);
186 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
187 printf("\tunknown22:[0x%x]\n", i0->unknown22);
188 printf("\tunknown23:[0x%x]\n", i0->unknown23);
189 printf("\tunknown24:[0x%x]\n", i0->unknown24);
190 printf("\tunknown25:[0x%x]\n", i0->unknown25);
191 printf("\tunknown26:[0x%x]\n", i0->unknown26);
192 printf("\tunknown27:[0x%x]\n", i0->unknown27);
193 printf("\tunknown28:[0x%x]\n", i0->unknown28);
194 printf("\tunknown29:[0x%x]\n", i0->unknown29);
199 /****************************************************************************
200 printer info level 1 display function
201 ****************************************************************************/
202 static void display_print_info_1(PRINTER_INFO_1 *i1)
208 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
211 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
212 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
214 printf("\tflags:[0x%x]\n", i1->flags);
215 printf("\tname:[%s]\n", name);
216 printf("\tdescription:[%s]\n", desc);
217 printf("\tcomment:[%s]\n", comm);
222 /****************************************************************************
223 printer info level 2 display function
224 ****************************************************************************/
225 static void display_print_info_2(PRINTER_INFO_2 *i2)
227 fstring servername = "";
228 fstring printername = "";
229 fstring sharename = "";
230 fstring portname = "";
231 fstring drivername = "";
232 fstring comment = "";
233 fstring location = "";
234 fstring sepfile = "";
235 fstring printprocessor = "";
236 fstring datatype = "";
237 fstring parameters = "";
239 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
241 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
243 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
245 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
247 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
249 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
251 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
253 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
255 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
257 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
259 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
261 printf("\tservername:[%s]\n", servername);
262 printf("\tprintername:[%s]\n", printername);
263 printf("\tsharename:[%s]\n", sharename);
264 printf("\tportname:[%s]\n", portname);
265 printf("\tdrivername:[%s]\n", drivername);
266 printf("\tcomment:[%s]\n", comment);
267 printf("\tlocation:[%s]\n", location);
268 printf("\tsepfile:[%s]\n", sepfile);
269 printf("\tprintprocessor:[%s]\n", printprocessor);
270 printf("\tdatatype:[%s]\n", datatype);
271 printf("\tparameters:[%s]\n", parameters);
272 printf("\tattributes:[0x%x]\n", i2->attributes);
273 printf("\tpriority:[0x%x]\n", i2->priority);
274 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
275 printf("\tstarttime:[0x%x]\n", i2->starttime);
276 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
277 printf("\tstatus:[0x%x]\n", i2->status);
278 printf("\tcjobs:[0x%x]\n", i2->cjobs);
279 printf("\taverageppm:[0x%x]\n", i2->averageppm);
282 display_sec_desc(i2->secdesc);
287 /****************************************************************************
288 printer info level 3 display function
289 ****************************************************************************/
290 static void display_print_info_3(PRINTER_INFO_3 *i3)
292 printf("\tflags:[0x%x]\n", i3->flags);
294 display_sec_desc(i3->secdesc);
299 /* Enumerate printers */
301 static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli,
303 int argc, const char **argv)
306 uint32 info_level = 1;
307 PRINTER_INFO_CTR ctr;
308 uint32 i = 0, num_printers, needed;
313 printf("Usage: %s [level] [name]\n", argv[0]);
318 info_level = atoi(argv[1]);
321 fstrcpy(name, argv[2]);
323 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
327 /* Enumerate printers -- Should we enumerate types other
328 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
332 result = cli_spoolss_enum_printers(
333 cli, mem_ctx, 0, &needed, name, PRINTER_ENUM_LOCAL,
334 info_level, &num_printers, &ctr);
336 if (W_ERROR_V(result) == ERRinsufficientbuffer)
337 result = cli_spoolss_enum_printers(
338 cli, mem_ctx, needed, NULL, name, PRINTER_ENUM_LOCAL,
339 info_level, &num_printers, &ctr);
341 if (W_ERROR_IS_OK(result)) {
344 printf ("No printers returned.\n");
348 for (i = 0; i < num_printers; i++) {
351 display_print_info_0(&ctr.printers_0[i]);
354 display_print_info_1(&ctr.printers_1[i]);
357 display_print_info_2(&ctr.printers_2[i]);
360 display_print_info_3(&ctr.printers_3[i]);
363 printf("unknown info level %d\n", info_level);
370 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
373 /****************************************************************************
374 port info level 1 display function
375 ****************************************************************************/
376 static void display_port_info_1(PORT_INFO_1 *i1)
380 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
381 printf("\tPort Name:\t[%s]\n", buffer);
384 /****************************************************************************
385 port info level 2 display function
386 ****************************************************************************/
387 static void display_port_info_2(PORT_INFO_2 *i2)
391 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
392 printf("\tPort Name:\t[%s]\n", buffer);
393 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
395 printf("\tMonitor Name:\t[%s]\n", buffer);
396 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
398 printf("\tDescription:\t[%s]\n", buffer);
399 printf("\tPort Type:\t[%d]\n", i2->port_type);
400 printf("\tReserved:\t[%d]\n", i2->reserved);
404 /* Enumerate ports */
406 static NTSTATUS cmd_spoolss_enum_ports(struct cli_state *cli,
407 TALLOC_CTX *mem_ctx, int argc,
411 uint32 needed, info_level = 1;
416 printf("Usage: %s [level]\n", argv[0]);
421 info_level = atoi(argv[1]);
423 /* Enumerate ports */
427 result = cli_spoolss_enum_ports(cli, mem_ctx, 0, &needed, info_level,
430 if (W_ERROR_V(result) == ERRinsufficientbuffer)
431 result = cli_spoolss_enum_ports(cli, mem_ctx, needed, NULL,
432 info_level, &returned, &ctr);
434 if (W_ERROR_IS_OK(result)) {
437 for (i = 0; i < returned; i++) {
438 switch (info_level) {
440 display_port_info_1(&ctr.port.info_1[i]);
443 display_port_info_2(&ctr.port.info_2[i]);
446 printf("unknown info level %d\n", info_level);
452 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
455 /***********************************************************************
456 * Set printer comment - use a level2 set.
458 static NTSTATUS cmd_spoolss_setprinter(struct cli_state *cli,
460 int argc, const char **argv)
465 uint32 info_level = 2;
466 BOOL opened_hnd = False;
467 PRINTER_INFO_CTR ctr;
473 if (argc == 1 || argc > 3) {
474 printf("Usage: %s printername comment\n", argv[0]);
479 /* Open a printer handle */
481 fstrcpy(comment, argv[2]);
484 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
485 strupper (servername);
486 fstrcpy (printername, argv[1]);
487 fstrcpy (user, cli->user_name);
489 /* get a printer handle */
490 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
491 MAXIMUM_ALLOWED_ACCESS, servername,
494 if (!W_ERROR_IS_OK(result))
499 /* Get printer info */
500 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, info_level, &ctr);
502 if (W_ERROR_V(result) == ERRinsufficientbuffer)
503 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
505 if (!W_ERROR_IS_OK(result))
509 /* Modify the comment. */
510 init_unistr(&ctr.printers_2->comment, comment);
511 ctr.printers_2->devmode = NULL;
512 ctr.printers_2->secdesc = NULL;
514 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
515 if (W_ERROR_IS_OK(result))
516 printf("Success in setting comment.\n");
520 cli_spoolss_close_printer(cli, mem_ctx, &pol);
522 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
525 /***********************************************************************
526 * Get printer information
528 static NTSTATUS cmd_spoolss_getprinter(struct cli_state *cli,
530 int argc, const char **argv)
534 uint32 info_level = 1;
535 BOOL opened_hnd = False;
536 PRINTER_INFO_CTR ctr;
542 if (argc == 1 || argc > 3) {
543 printf("Usage: %s <printername> [level]\n", argv[0]);
547 /* Open a printer handle */
549 info_level = atoi(argv[2]);
552 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
553 strupper (servername);
554 slprintf (printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
555 fstrcpy (user, cli->user_name);
557 /* get a printer handle */
559 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
560 "", MAXIMUM_ALLOWED_ACCESS,
561 servername, user, &pol);
563 if (!W_ERROR_IS_OK(result))
568 /* Get printer info */
570 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
571 &pol, info_level, &ctr);
573 if (W_ERROR_V(result) == ERRinsufficientbuffer)
574 result = cli_spoolss_getprinter(
575 cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
577 if (!W_ERROR_IS_OK(result))
580 /* Display printer info */
582 switch (info_level) {
584 display_print_info_0(ctr.printers_0);
587 display_print_info_1(ctr.printers_1);
590 display_print_info_2(ctr.printers_2);
593 display_print_info_3(ctr.printers_3);
596 printf("unknown info level %d\n", info_level);
602 cli_spoolss_close_printer(cli, mem_ctx, &pol);
604 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
607 static void display_reg_value(REGISTRY_VALUE value)
613 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
614 *((uint32 *) value.data_p));
617 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
619 printf("%s: REG_SZ: %s\n", value.valuename, text);
622 printf("%s: REG_BINARY: unknown length value not displayed\n",
626 uint16 *curstr = (uint16 *) value.data_p;
627 uint8 *start = value.data_p;
628 printf("%s: REG_MULTI_SZ:\n", value.valuename);
629 while ((*curstr != 0) &&
630 ((uint8 *) curstr < start + value.size)) {
631 rpcstr_pull(text, curstr, sizeof(text), -1,
633 printf(" %s\n", text);
634 curstr += strlen(text) + 1;
639 printf("%s: unknown type %d\n", value.valuename, value.type);
644 /***********************************************************************
647 static NTSTATUS cmd_spoolss_getprinterdata(struct cli_state *cli,
649 int argc, const char **argv)
653 BOOL opened_hnd = False;
658 const char *valuename;
659 REGISTRY_VALUE value;
662 printf("Usage: %s <printername> <valuename>\n", argv[0]);
663 printf("<printername> of . queries print server\n");
668 /* Open a printer handle */
670 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
671 strupper (servername);
672 if (strncmp(argv[1], ".", sizeof(".")) == 0)
673 fstrcpy(printername, servername);
675 slprintf (printername, sizeof(servername)-1, "%s\\%s",
676 servername, argv[1]);
677 fstrcpy (user, cli->user_name);
679 /* get a printer handle */
681 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
682 "", MAXIMUM_ALLOWED_ACCESS,
683 servername, user, &pol);
685 if (!W_ERROR_IS_OK(result))
690 /* Get printer info */
692 result = cli_spoolss_getprinterdata(cli, mem_ctx, 0, &needed,
693 &pol, valuename, &value);
695 if (W_ERROR_V(result) == ERRmoredata)
696 result = cli_spoolss_getprinterdata(
697 cli, mem_ctx, needed, NULL, &pol, valuename, &value);
699 if (!W_ERROR_IS_OK(result))
702 /* Display printer data */
704 fstrcpy(value.valuename, valuename);
705 display_reg_value(value);
710 cli_spoolss_close_printer(cli, mem_ctx, &pol);
712 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
715 /***********************************************************************
718 static NTSTATUS cmd_spoolss_getprinterdataex(struct cli_state *cli,
720 int argc, const char **argv)
724 BOOL opened_hnd = False;
729 const char *valuename, *keyname;
730 REGISTRY_VALUE value;
733 printf("Usage: %s <printername> <keyname> <valuename>\n",
735 printf("<printername> of . queries print server\n");
741 /* Open a printer handle */
743 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
744 strupper (servername);
745 if (strncmp(argv[1], ".", sizeof(".")) == 0)
746 fstrcpy(printername, servername);
748 slprintf (printername, sizeof(printername)-1, "%s\\%s",
749 servername, argv[1]);
750 fstrcpy (user, cli->user_name);
752 /* get a printer handle */
754 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
755 "", MAXIMUM_ALLOWED_ACCESS,
756 servername, user, &pol);
758 if (!W_ERROR_IS_OK(result))
763 /* Get printer info */
765 result = cli_spoolss_getprinterdataex(cli, mem_ctx, 0, &needed,
766 &pol, keyname, valuename,
769 if (W_ERROR_V(result) == ERRmoredata)
770 result = cli_spoolss_getprinterdataex(cli, mem_ctx, needed,
774 if (!W_ERROR_IS_OK(result))
777 /* Display printer data */
779 fstrcpy(value.valuename, valuename);
780 display_reg_value(value);
785 cli_spoolss_close_printer(cli, mem_ctx, &pol);
787 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
790 /****************************************************************************
791 printer info level 0 display function
792 ****************************************************************************/
793 static void display_print_driver_1(DRIVER_INFO_1 *i1)
799 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
801 printf ("Printer Driver Info 1:\n");
802 printf ("\tDriver Name: [%s]\n\n", name);
807 /****************************************************************************
808 printer info level 1 display function
809 ****************************************************************************/
810 static void display_print_driver_2(DRIVER_INFO_2 *i1)
813 fstring architecture;
820 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
821 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
822 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
823 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
824 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
826 printf ("Printer Driver Info 2:\n");
827 printf ("\tVersion: [%x]\n", i1->version);
828 printf ("\tDriver Name: [%s]\n", name);
829 printf ("\tArchitecture: [%s]\n", architecture);
830 printf ("\tDriver Path: [%s]\n", driverpath);
831 printf ("\tDatafile: [%s]\n", datafile);
832 printf ("\tConfigfile: [%s]\n\n", configfile);
837 /****************************************************************************
838 printer info level 2 display function
839 ****************************************************************************/
840 static void display_print_driver_3(DRIVER_INFO_3 *i1)
843 fstring architecture = "";
844 fstring driverpath = "";
845 fstring datafile = "";
846 fstring configfile = "";
847 fstring helpfile = "";
848 fstring dependentfiles = "";
849 fstring monitorname = "";
850 fstring defaultdatatype = "";
858 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
859 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
860 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
861 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
862 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
863 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
864 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
865 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
867 printf ("Printer Driver Info 3:\n");
868 printf ("\tVersion: [%x]\n", i1->version);
869 printf ("\tDriver Name: [%s]\n",name);
870 printf ("\tArchitecture: [%s]\n", architecture);
871 printf ("\tDriver Path: [%s]\n", driverpath);
872 printf ("\tDatafile: [%s]\n", datafile);
873 printf ("\tConfigfile: [%s]\n", configfile);
874 printf ("\tHelpfile: [%s]\n\n", helpfile);
878 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
880 length+=strlen(dependentfiles)+1;
882 if (strlen(dependentfiles) > 0)
884 printf ("\tDependentfiles: [%s]\n", dependentfiles);
894 printf ("\tMonitorname: [%s]\n", monitorname);
895 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
900 /***********************************************************************
901 * Get printer information
903 static NTSTATUS cmd_spoolss_getdriver(struct cli_state *cli,
905 int argc, const char **argv)
910 uint32 info_level = 3;
911 BOOL opened_hnd = False;
912 PRINTER_DRIVER_CTR ctr;
918 if ((argc == 1) || (argc > 3))
920 printf("Usage: %s <printername> [level]\n", argv[0]);
924 /* get the arguments need to open the printer handle */
925 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
926 strupper (servername);
927 fstrcpy (user, cli->user_name);
928 fstrcpy (printername, argv[1]);
930 info_level = atoi(argv[2]);
932 /* Open a printer handle */
934 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
936 servername, user, &pol);
938 result = W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
940 if (!NT_STATUS_IS_OK(result)) {
941 printf("Error opening printer handle for %s!\n", printername);
947 /* loop through and print driver info level for each architecture */
949 for (i=0; archi_table[i].long_archi!=NULL; i++) {
952 werror = cli_spoolss_getprinterdriver(
953 cli, mem_ctx, 0, &needed, &pol, info_level,
954 archi_table[i].long_archi, &ctr);
956 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
957 werror = cli_spoolss_getprinterdriver(
958 cli, mem_ctx, needed, NULL, &pol, info_level,
959 archi_table[i].long_archi, &ctr);
961 if (!W_ERROR_IS_OK(werror))
964 printf ("\n[%s]\n", archi_table[i].long_archi);
966 switch (info_level) {
968 display_print_driver_1 (ctr.info1);
971 display_print_driver_2 (ctr.info2);
974 display_print_driver_3 (ctr.info3);
977 printf("unknown info level %d\n", info_level);
985 cli_spoolss_close_printer (cli, mem_ctx, &pol);
987 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
990 /***********************************************************************
991 * Get printer information
993 static NTSTATUS cmd_spoolss_enum_drivers(struct cli_state *cli,
995 int argc, const char **argv)
998 uint32 info_level = 1;
999 PRINTER_DRIVER_CTR ctr;
1005 printf("Usage: enumdrivers [level]\n");
1006 return NT_STATUS_OK;
1010 info_level = atoi(argv[1]);
1013 /* loop through and print driver info level for each architecture */
1014 for (i=0; archi_table[i].long_archi!=NULL; i++)
1018 werror = cli_spoolss_enumprinterdrivers(
1019 cli, mem_ctx, 0, &needed, info_level,
1020 archi_table[i].long_archi, &returned, &ctr);
1022 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1023 werror = cli_spoolss_enumprinterdrivers(
1024 cli, mem_ctx, needed, NULL, info_level,
1025 archi_table[i].long_archi, &returned, &ctr);
1030 if (!W_ERROR_IS_OK(werror)) {
1031 printf ("Error getting driver for environment [%s] - %d\n",
1032 archi_table[i].long_archi, W_ERROR_V(werror));
1036 printf ("\n[%s]\n", archi_table[i].long_archi);
1041 for (j=0; j < returned; j++) {
1042 display_print_driver_1 (&(ctr.info1[j]));
1046 for (j=0; j < returned; j++) {
1047 display_print_driver_2 (&(ctr.info2[j]));
1051 for (j=0; j < returned; j++) {
1052 display_print_driver_3 (&(ctr.info3[j]));
1056 printf("unknown info level %d\n", info_level);
1061 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1064 /****************************************************************************
1065 printer info level 1 display function
1066 ****************************************************************************/
1067 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1073 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1075 printf ("\tDirectory Name:[%s]\n", name);
1078 /***********************************************************************
1079 * Get printer driver directory information
1081 static NTSTATUS cmd_spoolss_getdriverdir(struct cli_state *cli,
1082 TALLOC_CTX *mem_ctx,
1083 int argc, const char **argv)
1087 DRIVER_DIRECTORY_CTR ctr;
1091 printf("Usage: %s [environment]\n", argv[0]);
1092 return NT_STATUS_OK;
1095 /* Get the arguments need to open the printer handle */
1098 fstrcpy (env, argv[1]);
1100 fstrcpy (env, "Windows NT x86");
1102 /* Get the directory. Only use Info level 1 */
1104 result = cli_spoolss_getprinterdriverdir(
1105 cli, mem_ctx, 0, &needed, 1, env, &ctr);
1107 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1108 result = cli_spoolss_getprinterdriverdir(
1109 cli, mem_ctx, needed, NULL, 1, env, &ctr);
1111 if (W_ERROR_IS_OK(result))
1112 display_printdriverdir_1(ctr.info1);
1114 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1117 /*******************************************************************************
1118 set the version and environment fields of a DRIVER_INFO_3 struct
1119 ******************************************************************************/
1120 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1125 for (i=0; archi_table[i].long_archi != NULL; i++)
1127 if (strcmp(arch, archi_table[i].short_archi) == 0)
1129 info->version = archi_table[i].version;
1130 init_unistr (&info->architecture, archi_table[i].long_archi);
1135 if (archi_table[i].long_archi == NULL)
1137 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1144 /**************************************************************************
1145 wrapper for strtok to get the next parameter from a delimited list.
1146 Needed to handle the empty parameter string denoted by "NULL"
1147 *************************************************************************/
1148 static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
1152 /* get the next token */
1153 ptr = strtok(str, delim);
1155 /* a string of 'NULL' is used to represent an empty
1156 parameter because two consecutive delimiters
1157 will not return an empty string. See man strtok(3)
1159 if (StrCaseCmp(ptr, "NULL") == 0)
1163 init_unistr(dest, ptr);
1168 /********************************************************************************
1169 fill in the members of a DRIVER_INFO_3 struct using a character
1170 string in the form of
1171 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1172 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1173 <Default Data Type>:<Comma Separated list of Files>
1174 *******************************************************************************/
1175 static BOOL init_drv_info_3_members (
1176 TALLOC_CTX *mem_ctx,
1177 DRIVER_INFO_3 *info,
1184 /* fill in the UNISTR fields */
1185 str = get_driver_3_param (args, ":", &info->name);
1186 str = get_driver_3_param (NULL, ":", &info->driverpath);
1187 str = get_driver_3_param (NULL, ":", &info->datafile);
1188 str = get_driver_3_param (NULL, ":", &info->configfile);
1189 str = get_driver_3_param (NULL, ":", &info->helpfile);
1190 str = get_driver_3_param (NULL, ":", &info->monitorname);
1191 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1193 /* <Comma Separated List of Dependent Files> */
1194 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1197 /* begin to strip out each filename */
1198 str = strtok(str, ",");
1202 /* keep a cumlative count of the str lengths */
1203 len += strlen(str)+1;
1204 str = strtok(NULL, ",");
1207 /* allocate the space; add one extra slot for a terminating NULL.
1208 Each filename is NULL terminated and the end contains a double
1210 if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL)
1212 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1215 for (i=0; i<len; i++)
1217 info->dependentfiles[i] = SSVAL(&info->dependentfiles[i], 0, str2[i]);
1219 info->dependentfiles[len] = '\0';
1225 static NTSTATUS cmd_spoolss_addprinterdriver(struct cli_state *cli,
1226 TALLOC_CTX *mem_ctx,
1227 int argc, const char **argv)
1231 PRINTER_DRIVER_CTR ctr;
1232 DRIVER_INFO_3 info3;
1234 fstring driver_name;
1236 /* parse the command arguements */
1239 printf ("Usage: %s <Environment>\\\n", argv[0]);
1240 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1241 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1242 printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
1244 return NT_STATUS_OK;
1247 /* Fill in the DRIVER_INFO_3 struct */
1249 if (!get_short_archi(arch, argv[1]))
1251 printf ("Error Unknown architechture [%s]\n", argv[1]);
1252 return NT_STATUS_INVALID_PARAMETER;
1255 set_drv_info_3_env(&info3, arch);
1257 if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
1259 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1260 return NT_STATUS_INVALID_PARAMETER;
1265 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1267 if (W_ERROR_IS_OK(result)) {
1268 rpcstr_pull(driver_name, info3.name.buffer,
1269 sizeof(driver_name), -1, STR_TERMINATE);
1270 printf ("Printer Driver %s successfully installed.\n",
1274 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1278 static NTSTATUS cmd_spoolss_addprinterex(struct cli_state *cli,
1279 TALLOC_CTX *mem_ctx,
1280 int argc, const char **argv)
1284 PRINTER_INFO_CTR ctr;
1285 PRINTER_INFO_2 info2;
1288 /* parse the command arguements */
1291 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1292 return NT_STATUS_OK;
1295 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1296 strupper (servername);
1298 /* Fill in the DRIVER_INFO_3 struct */
1301 init_unistr( &info2.servername, servername);
1303 init_unistr( &info2.printername, argv[1]);
1304 init_unistr( &info2.sharename, argv[2]);
1305 init_unistr( &info2.drivername, argv[3]);
1306 init_unistr( &info2.portname, argv[4]);
1307 init_unistr( &info2.comment, "Created by rpcclient");
1308 init_unistr( &info2.printprocessor, "winprint");
1309 init_unistr( &info2.datatype, "RAW");
1310 info2.devmode = NULL;
1311 info2.secdesc = NULL;
1312 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1314 info2.defaultpriority = 0;
1315 info2.starttime = 0;
1316 info2.untiltime = 0;
1318 /* These three fields must not be used by AddPrinter()
1319 as defined in the MS Platform SDK documentation..
1323 info2.averageppm = 0;
1326 ctr.printers_2 = &info2;
1327 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1329 if (W_ERROR_IS_OK(result))
1330 printf ("Printer %s successfully installed.\n", argv[1]);
1332 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1335 static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli,
1336 TALLOC_CTX *mem_ctx,
1337 int argc, const char **argv)
1342 BOOL opened_hnd = False;
1343 PRINTER_INFO_CTR ctr;
1344 PRINTER_INFO_2 info2;
1350 /* parse the command arguements */
1353 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1354 return NT_STATUS_OK;
1357 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1358 strupper (servername);
1359 slprintf (printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1360 fstrcpy (user, cli->user_name);
1362 /* Get a printer handle */
1364 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1365 MAXIMUM_ALLOWED_ACCESS,
1366 servername, user, &pol);
1368 if (!W_ERROR_IS_OK(result))
1373 /* Get printer info */
1375 ZERO_STRUCT (info2);
1376 ctr.printers_2 = &info2;
1378 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1381 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1382 result = cli_spoolss_getprinter(
1383 cli, mem_ctx, needed, NULL, &pol, level, &ctr);
1385 if (!W_ERROR_IS_OK(result)) {
1386 printf ("Unable to retrieve printer information!\n");
1390 /* Set the printer driver */
1392 init_unistr(&ctr.printers_2->drivername, argv[2]);
1394 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1396 if (!W_ERROR_IS_OK(result)) {
1397 printf("SetPrinter call failed!\n");
1401 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1407 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1409 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1413 static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli,
1414 TALLOC_CTX *mem_ctx,
1415 int argc, const char **argv)
1421 /* parse the command arguements */
1424 printf ("Usage: %s <driver>\n", argv[0]);
1425 return NT_STATUS_OK;
1428 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1429 strupper (servername);
1431 /* delete the driver for all architectures */
1432 for (i=0; archi_table[i].long_archi; i++)
1434 /* make the call to remove the driver */
1435 result = cli_spoolss_deleteprinterdriver(
1436 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1438 if ( !W_ERROR_IS_OK(result) ) {
1439 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1440 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1441 argv[1], archi_table[i].long_archi,
1447 printf ("Driver %s removed for arch [%s].\n", argv[1],
1448 archi_table[i].long_archi);
1452 return W_ERROR_IS_OK(result) || W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1455 static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli,
1456 TALLOC_CTX *mem_ctx,
1457 int argc, const char **argv)
1460 char *servername = NULL, *environment = NULL;
1464 /* parse the command arguements */
1466 printf ("Usage: %s [environment]\n", argv[0]);
1467 return NT_STATUS_OK;
1470 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1471 return NT_STATUS_NO_MEMORY;
1472 strupper(servername);
1474 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1475 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1476 SAFE_FREE(servername);
1477 return NT_STATUS_NO_MEMORY;
1480 result = cli_spoolss_getprintprocessordirectory(
1481 cli, mem_ctx, 0, &needed, servername, environment, procdir);
1483 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1484 result = cli_spoolss_getprintprocessordirectory(
1485 cli, mem_ctx, needed, NULL, servername, environment,
1488 if (W_ERROR_IS_OK(result))
1489 printf("%s\n", procdir);
1491 SAFE_FREE(servername);
1492 SAFE_FREE(environment);
1494 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1499 static NTSTATUS cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1500 int argc, const char **argv)
1504 char *servername = NULL, *printername = NULL;
1506 BOOL got_handle = False;
1508 /* Parse the command arguements */
1511 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1512 return NT_STATUS_OK;
1515 /* Get a printer handle */
1517 asprintf(&servername, "\\\\%s", cli->desthost);
1518 strupper(servername);
1519 asprintf(&printername, "%s\\%s", servername, argv[1]);
1521 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1522 MAXIMUM_ALLOWED_ACCESS,
1523 servername, cli->user_name, &handle);
1525 if (!W_ERROR_IS_OK(werror))
1530 /* Dummy up some values for the form data */
1532 form.flags = FORM_USER;
1533 form.size_x = form.size_y = 100;
1539 init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
1544 werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1548 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1550 SAFE_FREE(servername);
1551 SAFE_FREE(printername);
1553 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1558 static NTSTATUS cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1559 int argc, const char **argv)
1563 char *servername = NULL, *printername = NULL;
1565 BOOL got_handle = False;
1567 /* Parse the command arguements */
1570 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1571 return NT_STATUS_OK;
1574 /* Get a printer handle */
1576 asprintf(&servername, "\\\\%s", cli->desthost);
1577 strupper(servername);
1578 asprintf(&printername, "%s\\%s", servername, argv[1]);
1580 werror = cli_spoolss_open_printer_ex(
1581 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1582 servername, cli->user_name, &handle);
1584 if (!W_ERROR_IS_OK(werror))
1589 /* Dummy up some values for the form data */
1591 form.flags = FORM_PRINTER;
1592 form.size_x = form.size_y = 100;
1598 init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
1602 werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1606 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1608 SAFE_FREE(servername);
1609 SAFE_FREE(printername);
1611 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1616 static NTSTATUS cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1617 int argc, const char **argv)
1621 char *servername = NULL, *printername = NULL;
1623 BOOL got_handle = False;
1626 /* Parse the command arguements */
1629 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1630 return NT_STATUS_OK;
1633 /* Get a printer handle */
1635 asprintf(&servername, "\\\\%s", cli->desthost);
1636 strupper(servername);
1637 asprintf(&printername, "%s\\%s", servername, argv[1]);
1639 werror = cli_spoolss_open_printer_ex(
1640 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1641 servername, cli->user_name, &handle);
1643 if (!W_ERROR_IS_OK(werror))
1650 werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
1651 &handle, argv[2], 1, &form);
1653 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1654 werror = cli_spoolss_getform(cli, mem_ctx, needed, NULL,
1655 &handle, argv[2], 1, &form);
1657 if (!W_ERROR_IS_OK(werror))
1660 printf("width: %d\n", form.width);
1661 printf("length: %d\n", form.length);
1662 printf("left: %d\n", form.left);
1663 printf("top: %d\n", form.top);
1664 printf("right: %d\n", form.right);
1665 printf("bottom: %d\n", form.bottom);
1669 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1671 SAFE_FREE(servername);
1672 SAFE_FREE(printername);
1674 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1679 static NTSTATUS cmd_spoolss_deleteform(struct cli_state *cli,
1680 TALLOC_CTX *mem_ctx, int argc,
1685 char *servername = NULL, *printername = NULL;
1686 BOOL got_handle = False;
1688 /* Parse the command arguements */
1691 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1692 return NT_STATUS_OK;
1695 /* Get a printer handle */
1697 asprintf(&servername, "\\\\%s", cli->desthost);
1698 strupper(servername);
1699 asprintf(&printername, "%s\\%s", servername, argv[1]);
1701 werror = cli_spoolss_open_printer_ex(
1702 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1703 servername, cli->user_name, &handle);
1705 if (!W_ERROR_IS_OK(werror))
1710 /* Delete the form */
1712 werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1716 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1718 SAFE_FREE(servername);
1719 SAFE_FREE(printername);
1721 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1724 /* Enumerate forms */
1726 static NTSTATUS cmd_spoolss_enum_forms(struct cli_state *cli,
1727 TALLOC_CTX *mem_ctx, int argc,
1732 char *servername = NULL, *printername = NULL;
1733 BOOL got_handle = False;
1734 uint32 needed, num_forms, level = 1, i;
1737 /* Parse the command arguements */
1740 printf ("Usage: %s <printer>\n", argv[0]);
1741 return NT_STATUS_OK;
1744 /* Get a printer handle */
1746 asprintf(&servername, "\\\\%s", cli->desthost);
1747 strupper(servername);
1748 asprintf(&printername, "%s\\%s", servername, argv[1]);
1750 werror = cli_spoolss_open_printer_ex(
1751 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1752 servername, cli->user_name, &handle);
1754 if (!W_ERROR_IS_OK(werror))
1759 /* Enumerate forms */
1761 werror = cli_spoolss_enumforms(
1762 cli, mem_ctx, 0, &needed, &handle, level, &num_forms, &forms);
1764 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1765 werror = cli_spoolss_enumforms(
1766 cli, mem_ctx, needed, NULL, &handle, level,
1767 &num_forms, &forms);
1769 if (!W_ERROR_IS_OK(werror))
1772 /* Display output */
1774 for (i = 0; i < num_forms; i++) {
1777 if (forms[i].name.buffer)
1778 rpcstr_pull(form_name, forms[i].name.buffer,
1779 sizeof(form_name), -1, STR_TERMINATE);
1781 printf("%s\n", form_name);
1786 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1788 SAFE_FREE(servername);
1789 SAFE_FREE(printername);
1791 return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1794 static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli,
1795 TALLOC_CTX *mem_ctx,
1796 int argc, const char **argv)
1800 fstring servername, printername, user;
1802 BOOL opened_hnd = False;
1803 PRINTER_INFO_CTR ctr;
1804 PRINTER_INFO_0 info;
1805 REGISTRY_VALUE value;
1807 /* parse the command arguements */
1809 printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
1810 return NT_STATUS_OK;
1813 slprintf (servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1814 strupper (servername);
1815 slprintf (printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1816 fstrcpy (user, cli->user_name);
1818 /* get a printer handle */
1819 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1820 MAXIMUM_ALLOWED_ACCESS, servername,
1822 if (!W_ERROR_IS_OK(result))
1827 ctr.printers_0 = &info;
1829 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1832 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1833 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1835 if (!W_ERROR_IS_OK(result))
1838 printf("%s\n", timestring(True));
1839 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
1841 /* Set the printer data */
1843 fstrcpy(value.valuename, argv[2]);
1844 value.type = REG_SZ;
1845 value.size = strlen(argv[3]) + 1;
1846 value.data_p = talloc_memdup(mem_ctx, argv[3], value.size);
1848 result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
1850 if (!W_ERROR_IS_OK(result)) {
1851 printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
1854 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
1856 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, 0, &ctr);
1858 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1859 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1861 if (!W_ERROR_IS_OK(result))
1864 printf("%s\n", timestring(True));
1865 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
1870 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1872 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1875 static void display_job_info_1(JOB_INFO_1 *job)
1877 fstring username = "", document = "", text_status = "";
1879 rpcstr_pull(username, job->username.buffer,
1880 sizeof(username), -1, STR_TERMINATE);
1882 rpcstr_pull(document, job->document.buffer,
1883 sizeof(document), -1, STR_TERMINATE);
1885 rpcstr_pull(text_status, job->text_status.buffer,
1886 sizeof(text_status), -1, STR_TERMINATE);
1888 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
1889 username, document, text_status, job->pagesprinted,
1893 static void display_job_info_2(JOB_INFO_2 *job)
1895 fstring username = "", document = "", text_status = "";
1897 rpcstr_pull(username, job->username.buffer,
1898 sizeof(username), -1, STR_TERMINATE);
1900 rpcstr_pull(document, job->document.buffer,
1901 sizeof(document), -1, STR_TERMINATE);
1903 rpcstr_pull(text_status, job->text_status.buffer,
1904 sizeof(text_status), -1, STR_TERMINATE);
1906 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
1907 username, document, text_status, job->pagesprinted,
1908 job->totalpages, job->size);
1911 /* Enumerate jobs */
1913 static NTSTATUS cmd_spoolss_enum_jobs(struct cli_state *cli,
1914 TALLOC_CTX *mem_ctx, int argc,
1918 uint32 needed, level = 1, num_jobs, i;
1919 BOOL got_hnd = False;
1920 pstring printername;
1921 fstring servername, user;
1925 if (argc < 2 || argc > 3) {
1926 printf("Usage: %s printername [level]\n", argv[0]);
1927 return NT_STATUS_OK;
1931 level = atoi(argv[2]);
1933 /* Open printer handle */
1935 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1936 strupper(servername);
1937 fstrcpy(user, cli->user_name);
1938 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
1939 strupper(printername);
1940 pstrcat(printername, argv[1]);
1942 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
1943 "", MAXIMUM_ALLOWED_ACCESS,
1944 servername, user, &hnd);
1946 if (!W_ERROR_IS_OK(result))
1951 /* Enumerate ports */
1953 result = cli_spoolss_enumjobs(
1954 cli, mem_ctx, 0, &needed, &hnd, level, 0, 1000,
1957 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1958 result = cli_spoolss_enumjobs(
1959 cli, mem_ctx, needed, NULL, &hnd, level, 0,
1960 1000, &num_jobs, &ctr);
1962 if (!W_ERROR_IS_OK(result))
1965 for (i = 0; i < num_jobs; i++) {
1968 display_job_info_1(&ctr.job.job_info_1[i]);
1971 display_job_info_2(&ctr.job.job_info_2[i]);
1974 d_printf("unknown info level %d\n", level);
1981 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
1983 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1986 /* enumerate data */
1988 static NTSTATUS cmd_spoolss_enum_data( struct cli_state *cli,
1989 TALLOC_CTX *mem_ctx, int argc,
1993 uint32 i=0, val_needed, data_needed;
1994 BOOL got_hnd = False;
1995 pstring printername;
1996 fstring servername, user;
2000 printf("Usage: %s printername\n", argv[0]);
2001 return NT_STATUS_OK;
2004 /* Open printer handle */
2006 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2007 strupper(servername);
2008 fstrcpy(user, cli->user_name);
2009 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2010 strupper(printername);
2011 pstrcat(printername, argv[1]);
2013 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2014 "", MAXIMUM_ALLOWED_ACCESS,
2015 servername, user, &hnd);
2017 if (!W_ERROR_IS_OK(result))
2022 /* Enumerate data */
2024 result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2025 &val_needed, &data_needed,
2027 while (W_ERROR_IS_OK(result)) {
2028 REGISTRY_VALUE value;
2029 result = cli_spoolss_enumprinterdata(
2030 cli, mem_ctx, &hnd, i++, val_needed,
2031 data_needed, 0, 0, &value);
2032 if (W_ERROR_IS_OK(result))
2033 display_reg_value(value);
2035 if (W_ERROR_V(result) == ERRnomoreitems)
2036 result = W_ERROR(ERRsuccess);
2040 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2042 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2045 /* enumerate data for a given key */
2047 static NTSTATUS cmd_spoolss_enum_data_ex( struct cli_state *cli,
2048 TALLOC_CTX *mem_ctx, int argc,
2053 BOOL got_hnd = False;
2054 pstring printername;
2055 fstring servername, user;
2056 const char *keyname = NULL;
2061 printf("Usage: %s printername <keyname>\n", argv[0]);
2062 return NT_STATUS_OK;
2067 /* Open printer handle */
2069 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2070 strupper(servername);
2071 fstrcpy(user, cli->user_name);
2072 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2073 strupper(printername);
2074 pstrcat(printername, argv[1]);
2076 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2077 "", MAXIMUM_ALLOWED_ACCESS,
2078 servername, user, &hnd);
2080 if (!W_ERROR_IS_OK(result))
2085 /* Enumerate subkeys */
2087 result = cli_spoolss_enumprinterdataex(
2088 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL);
2090 if (W_ERROR_V(result) == ERRmoredata)
2091 result = cli_spoolss_enumprinterdataex(
2092 cli, mem_ctx, needed, NULL, &hnd, keyname, &ctr);
2094 if (!W_ERROR_IS_OK(result))
2097 for (i=0; i < ctr.num_values; i++) {
2098 display_reg_value(*(ctr.values[i]));
2101 regval_ctr_destroy(&ctr);
2105 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2107 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2110 /* enumerate subkeys */
2112 static NTSTATUS cmd_spoolss_enum_printerkey( struct cli_state *cli,
2113 TALLOC_CTX *mem_ctx, int argc,
2117 uint32 needed, returned;
2118 BOOL got_hnd = False;
2119 pstring printername;
2120 fstring servername, user;
2121 const char *keyname = NULL;
2123 uint16 *keylist = NULL, *curkey;
2125 if (argc < 2 || argc > 3) {
2126 printf("Usage: %s printername [keyname]\n", argv[0]);
2127 return NT_STATUS_OK;
2135 /* Open printer handle */
2137 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2138 strupper(servername);
2139 fstrcpy(user, cli->user_name);
2140 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2141 strupper(printername);
2142 pstrcat(printername, argv[1]);
2144 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2145 "", MAXIMUM_ALLOWED_ACCESS,
2146 servername, user, &hnd);
2148 if (!W_ERROR_IS_OK(result))
2153 /* Enumerate subkeys */
2155 result = cli_spoolss_enumprinterkey(
2156 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL, NULL);
2158 if (W_ERROR_V(result) == ERRmoredata)
2159 result = cli_spoolss_enumprinterkey(
2160 cli, mem_ctx, needed, NULL, &hnd, keyname, &keylist,
2163 if (!W_ERROR_IS_OK(result))
2167 while (*curkey != 0) {
2169 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2171 printf("%s\n", subkey);
2172 curkey += strlen(subkey) + 1;
2179 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2181 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2184 static NTSTATUS cmd_spoolss_rffpcnex(struct cli_state *cli,
2185 TALLOC_CTX *mem_ctx, int argc,
2188 fstring servername, printername;
2190 BOOL got_hnd = False;
2192 SPOOL_NOTIFY_OPTION option;
2195 printf("Usage: %s printername\n", argv[0]);
2202 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2203 strupper(servername);
2205 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
2207 strupper(printername);
2209 result = cli_spoolss_open_printer_ex(
2210 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2211 servername, cli->user_name, &hnd);
2213 if (!W_ERROR_IS_OK(result)) {
2214 printf("Error opening %s\n", argv[1]);
2220 /* Create spool options */
2222 ZERO_STRUCT(option);
2225 option.option_type_ptr = 1;
2226 option.count = option.ctr.count = 2;
2228 option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc(
2229 mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2);
2231 ZERO_STRUCT(option.ctr.type[0]);
2232 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2233 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2234 option.ctr.type[0].fields_ptr = 1;
2235 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2237 ZERO_STRUCT(option.ctr.type[1]);
2238 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2239 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2240 option.ctr.type[1].fields_ptr = 1;
2241 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2245 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2246 strupper(servername);
2248 result = cli_spoolss_rffpcnex(
2249 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2251 if (!W_ERROR_IS_OK(result)) {
2252 printf("Error rffpcnex %s\n", argv[1]);
2258 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2260 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2263 /* List of commands exported by this module */
2264 struct cmd_set spoolss_commands[] = {
2268 { "adddriver", cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
2269 { "addprinter", cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
2270 { "deldriver", cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
2271 { "enumdata", cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
2272 { "enumdataex", cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
2273 { "enumkey", cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
2274 { "enumjobs", cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
2275 { "enumports", cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
2276 { "enumdrivers", cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
2277 { "enumprinters", cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
2278 { "getdata", cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
2279 { "getdataex", cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
2280 { "getdriver", cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
2281 { "getdriverdir", cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
2282 { "getprinter", cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
2283 { "getprintprocdir", cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2284 { "openprinter", cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
2285 { "setdriver", cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
2286 { "getprintprocdir", cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2287 { "addform", cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
2288 { "setform", cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
2289 { "getform", cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
2290 { "deleteform", cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
2291 { "enumforms", cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
2292 { "setprinter", cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
2293 { "setprinterdata", cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
2294 { "rffpcnex", cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },