Apply some more of Derrell Lipman's changes.
[Samba/gebeck_regimport.git] / source3 / rpcclient / cmd_spoolss.c
blobf5a440c024c455ffb36168555aa55a3f236660b1
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
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.
25 #include "includes.h"
26 #include "rpcclient.h"
28 struct table_node {
29 const char *long_archi;
30 const char *short_archi;
31 int version;
34 static const struct table_node archi_table[]= {
36 {"Windows 4.0", "WIN40", 0 },
37 {"Windows NT x86", "W32X86", 2 },
38 {"Windows NT x86", "W32X86", 3 },
39 {"Windows NT R4000", "W32MIPS", 2 },
40 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
41 {"Windows NT PowerPC", "W32PPC", 2 },
42 {NULL, "", -1 }
45 /**
46 * @file
48 * rpcclient module for SPOOLSS rpc pipe.
50 * This generally just parses and checks command lines, and then calls
51 * a cli_spoolss function.
52 **/
54 /****************************************************************************
55 function to do the mapping between the long architecture name and
56 the short one.
57 ****************************************************************************/
58 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
60 int i=-1;
62 DEBUG(107,("Getting architecture dependant directory\n"));
63 do {
64 i++;
65 } while ( (archi_table[i].long_archi!=NULL ) &&
66 StrCaseCmp(long_archi, archi_table[i].long_archi) );
68 if (archi_table[i].long_archi==NULL) {
69 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
70 return NULL;
73 /* this might be client code - but shouldn't this be an fstrcpy etc? */
76 DEBUGADD(108,("index: [%d]\n", i));
77 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
78 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
80 return archi_table[i].short_archi;
83 #if 0
84 /**********************************************************************
85 * dummy function -- placeholder
87 static WERROR cmd_spoolss_not_implemented(struct cli_state *cli,
88 TALLOC_CTX *mem_ctx,
89 int argc, const char **argv)
91 printf ("(*) This command is not currently implemented.\n");
92 return WERR_OK;
94 #endif
96 /***********************************************************************
97 * Get printer information
99 static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
100 TALLOC_CTX *mem_ctx,
101 int argc, const char **argv)
103 WERROR werror;
104 fstring printername;
105 fstring servername, user;
106 POLICY_HND hnd;
108 if (argc != 2) {
109 printf("Usage: %s <printername>\n", argv[0]);
110 return WERR_OK;
113 if (!cli)
114 return WERR_GENERAL_FAILURE;
116 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
117 strupper_m(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 werror;
141 /****************************************************************************
142 printer info level 0 display function
143 ****************************************************************************/
144 static void display_print_info_0(PRINTER_INFO_0 *i0)
146 fstring name = "";
147 fstring servername = "";
149 if (!i0)
150 return;
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);
196 printf("\n");
199 /****************************************************************************
200 printer info level 1 display function
201 ****************************************************************************/
202 static void display_print_info_1(PRINTER_INFO_1 *i1)
204 fstring desc = "";
205 fstring name = "";
206 fstring comm = "";
208 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
209 STR_TERMINATE);
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);
219 printf("\n");
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);
281 if (i2->secdesc)
282 display_sec_desc(i2->secdesc);
284 printf("\n");
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);
296 printf("\n");
299 /* Enumerate printers */
301 static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
302 TALLOC_CTX *mem_ctx,
303 int argc, const char **argv)
305 WERROR result;
306 uint32 info_level = 1;
307 PRINTER_INFO_CTR ctr;
308 uint32 i = 0, num_printers, needed;
309 fstring name;
311 if (argc > 3)
313 printf("Usage: %s [level] [name]\n", argv[0]);
314 return WERR_OK;
317 if (argc == 2)
318 info_level = atoi(argv[1]);
320 if (argc == 3)
321 fstrcpy(name, argv[2]);
322 else {
323 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
324 strupper_m(name);
327 /* Enumerate printers -- Should we enumerate types other
328 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
330 ZERO_STRUCT(ctr);
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)) {
343 if (!num_printers) {
344 printf ("No printers returned.\n");
345 goto done;
348 for (i = 0; i < num_printers; i++) {
349 switch(info_level) {
350 case 0:
351 display_print_info_0(&ctr.printers_0[i]);
352 break;
353 case 1:
354 display_print_info_1(&ctr.printers_1[i]);
355 break;
356 case 2:
357 display_print_info_2(&ctr.printers_2[i]);
358 break;
359 case 3:
360 display_print_info_3(&ctr.printers_3[i]);
361 break;
362 default:
363 printf("unknown info level %d\n", info_level);
364 goto done;
368 done:
370 return result;
373 /****************************************************************************
374 port info level 1 display function
375 ****************************************************************************/
376 static void display_port_info_1(PORT_INFO_1 *i1)
378 fstring buffer;
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)
389 fstring buffer;
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" );
400 if ( i2->port_type ) {
401 int comma = 0; /* hack */
402 printf( "[" );
403 if ( i2->port_type & PORT_TYPE_READ ) {
404 printf( "Read" );
405 comma = 1;
407 if ( i2->port_type & PORT_TYPE_WRITE ) {
408 printf( "%sWrite", comma ? ", " : "" );
409 comma = 1;
411 /* These two have slightly different interpretations
412 on 95/98/ME but I'm disregarding that for now */
413 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
414 printf( "%sRedirected", comma ? ", " : "" );
415 comma = 1;
417 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
418 printf( "%sNet-Attached", comma ? ", " : "" );
420 printf( "]\n" );
421 } else {
422 printf( "[Unset]\n" );
424 printf("\tReserved:\t[%d]\n", i2->reserved);
425 printf("\n");
428 /* Enumerate ports */
430 static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
431 TALLOC_CTX *mem_ctx, int argc,
432 const char **argv)
434 WERROR result;
435 uint32 needed, info_level = 1;
436 PORT_INFO_CTR ctr;
437 int returned;
439 if (argc > 2) {
440 printf("Usage: %s [level]\n", argv[0]);
441 return WERR_OK;
444 if (argc == 2)
445 info_level = atoi(argv[1]);
447 /* Enumerate ports */
449 ZERO_STRUCT(ctr);
451 result = cli_spoolss_enum_ports(cli, mem_ctx, 0, &needed, info_level,
452 &returned, &ctr);
454 if (W_ERROR_V(result) == ERRinsufficientbuffer)
455 result = cli_spoolss_enum_ports(cli, mem_ctx, needed, NULL,
456 info_level, &returned, &ctr);
458 if (W_ERROR_IS_OK(result)) {
459 int i;
461 for (i = 0; i < returned; i++) {
462 switch (info_level) {
463 case 1:
464 display_port_info_1(&ctr.port.info_1[i]);
465 break;
466 case 2:
467 display_port_info_2(&ctr.port.info_2[i]);
468 break;
469 default:
470 printf("unknown info level %d\n", info_level);
471 break;
476 return result;
479 /***********************************************************************
480 * Set printer comment - use a level2 set.
482 static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
483 TALLOC_CTX *mem_ctx,
484 int argc, const char **argv)
486 POLICY_HND pol;
487 WERROR result;
488 uint32 needed;
489 uint32 info_level = 2;
490 BOOL opened_hnd = False;
491 PRINTER_INFO_CTR ctr;
492 fstring printername,
493 servername,
494 user,
495 comment;
497 if (argc == 1 || argc > 3) {
498 printf("Usage: %s printername comment\n", argv[0]);
500 return WERR_OK;
503 /* Open a printer handle */
504 if (argc == 3) {
505 fstrcpy(comment, argv[2]);
508 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
509 strupper_m(servername);
510 fstrcpy(printername, argv[1]);
511 fstrcpy(user, cli->user_name);
513 /* get a printer handle */
514 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
515 PRINTER_ALL_ACCESS, servername,
516 user, &pol);
518 if (!W_ERROR_IS_OK(result))
519 goto done;
521 opened_hnd = True;
523 /* Get printer info */
524 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, info_level, &ctr);
526 if (W_ERROR_V(result) == ERRinsufficientbuffer)
527 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
529 if (!W_ERROR_IS_OK(result))
530 goto done;
533 /* Modify the comment. */
534 init_unistr(&ctr.printers_2->comment, comment);
535 ctr.printers_2->devmode = NULL;
536 ctr.printers_2->secdesc = NULL;
538 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
539 if (W_ERROR_IS_OK(result))
540 printf("Success in setting comment.\n");
542 done:
543 if (opened_hnd)
544 cli_spoolss_close_printer(cli, mem_ctx, &pol);
546 return result;
549 /***********************************************************************
550 * Get printer information
552 static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
553 TALLOC_CTX *mem_ctx,
554 int argc, const char **argv)
556 POLICY_HND pol;
557 WERROR result;
558 uint32 info_level = 1;
559 BOOL opened_hnd = False;
560 PRINTER_INFO_CTR ctr;
561 fstring printername,
562 servername,
563 user;
564 uint32 needed;
566 if (argc == 1 || argc > 3) {
567 printf("Usage: %s <printername> [level]\n", argv[0]);
568 return WERR_OK;
571 /* Open a printer handle */
572 if (argc == 3) {
573 info_level = atoi(argv[2]);
576 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
577 strupper_m(servername);
578 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
579 fstrcpy(user, cli->user_name);
581 /* get a printer handle */
583 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
584 "", MAXIMUM_ALLOWED_ACCESS,
585 servername, user, &pol);
587 if (!W_ERROR_IS_OK(result))
588 goto done;
590 opened_hnd = True;
592 /* Get printer info */
594 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
595 &pol, info_level, &ctr);
597 if (W_ERROR_V(result) == ERRinsufficientbuffer)
598 result = cli_spoolss_getprinter(
599 cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
601 if (!W_ERROR_IS_OK(result))
602 goto done;
604 /* Display printer info */
606 switch (info_level) {
607 case 0:
608 display_print_info_0(ctr.printers_0);
609 break;
610 case 1:
611 display_print_info_1(ctr.printers_1);
612 break;
613 case 2:
614 display_print_info_2(ctr.printers_2);
615 break;
616 case 3:
617 display_print_info_3(ctr.printers_3);
618 break;
619 default:
620 printf("unknown info level %d\n", info_level);
621 break;
624 done:
625 if (opened_hnd)
626 cli_spoolss_close_printer(cli, mem_ctx, &pol);
628 return result;
631 static void display_reg_value(REGISTRY_VALUE value)
633 pstring text;
635 switch(value.type) {
636 case REG_DWORD:
637 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
638 *((uint32 *) value.data_p));
639 break;
640 case REG_SZ:
641 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
642 STR_TERMINATE);
643 printf("%s: REG_SZ: %s\n", value.valuename, text);
644 break;
645 case REG_BINARY:
646 printf("%s: REG_BINARY: unknown length value not displayed\n",
647 value.valuename);
648 break;
649 case REG_MULTI_SZ: {
650 uint16 *curstr = (uint16 *) value.data_p;
651 uint8 *start = value.data_p;
652 printf("%s: REG_MULTI_SZ:\n", value.valuename);
653 while ((*curstr != 0) &&
654 ((uint8 *) curstr < start + value.size)) {
655 rpcstr_pull(text, curstr, sizeof(text), -1,
656 STR_TERMINATE);
657 printf(" %s\n", text);
658 curstr += strlen(text) + 1;
661 break;
662 default:
663 printf("%s: unknown type %d\n", value.valuename, value.type);
668 /***********************************************************************
669 * Get printer data
671 static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
672 TALLOC_CTX *mem_ctx,
673 int argc, const char **argv)
675 POLICY_HND pol;
676 WERROR result;
677 BOOL opened_hnd = False;
678 fstring printername,
679 servername,
680 user;
681 uint32 needed;
682 const char *valuename;
683 REGISTRY_VALUE value;
685 if (argc != 3) {
686 printf("Usage: %s <printername> <valuename>\n", argv[0]);
687 printf("<printername> of . queries print server\n");
688 return WERR_OK;
690 valuename = argv[2];
692 /* Open a printer handle */
694 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
695 strupper_m(servername);
696 if (strncmp(argv[1], ".", sizeof(".")) == 0)
697 fstrcpy(printername, servername);
698 else
699 slprintf(printername, sizeof(servername)-1, "%s\\%s",
700 servername, argv[1]);
701 fstrcpy(user, cli->user_name);
703 /* get a printer handle */
705 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
706 "", MAXIMUM_ALLOWED_ACCESS,
707 servername, user, &pol);
709 if (!W_ERROR_IS_OK(result))
710 goto done;
712 opened_hnd = True;
714 /* Get printer info */
716 result = cli_spoolss_getprinterdata(cli, mem_ctx, 0, &needed,
717 &pol, valuename, &value);
719 if (W_ERROR_V(result) == ERRmoredata)
720 result = cli_spoolss_getprinterdata(
721 cli, mem_ctx, needed, NULL, &pol, valuename, &value);
723 if (!W_ERROR_IS_OK(result))
724 goto done;
726 /* Display printer data */
728 fstrcpy(value.valuename, valuename);
729 display_reg_value(value);
732 done:
733 if (opened_hnd)
734 cli_spoolss_close_printer(cli, mem_ctx, &pol);
736 return result;
739 /***********************************************************************
740 * Get printer data
742 static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
743 TALLOC_CTX *mem_ctx,
744 int argc, const char **argv)
746 POLICY_HND pol;
747 WERROR result;
748 BOOL opened_hnd = False;
749 fstring printername,
750 servername,
751 user;
752 uint32 needed;
753 const char *valuename, *keyname;
754 REGISTRY_VALUE value;
756 if (argc != 4) {
757 printf("Usage: %s <printername> <keyname> <valuename>\n",
758 argv[0]);
759 printf("<printername> of . queries print server\n");
760 return WERR_OK;
762 valuename = argv[3];
763 keyname = argv[2];
765 /* Open a printer handle */
767 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
768 strupper_m(servername);
769 if (strncmp(argv[1], ".", sizeof(".")) == 0)
770 fstrcpy(printername, servername);
771 else
772 slprintf(printername, sizeof(printername)-1, "%s\\%s",
773 servername, argv[1]);
774 fstrcpy(user, cli->user_name);
776 /* get a printer handle */
778 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
779 "", MAXIMUM_ALLOWED_ACCESS,
780 servername, user, &pol);
782 if (!W_ERROR_IS_OK(result))
783 goto done;
785 opened_hnd = True;
787 /* Get printer info */
789 result = cli_spoolss_getprinterdataex(cli, mem_ctx, 0, &needed,
790 &pol, keyname, valuename,
791 &value);
793 if (W_ERROR_V(result) == ERRmoredata)
794 result = cli_spoolss_getprinterdataex(cli, mem_ctx, needed,
795 NULL, &pol, keyname,
796 valuename, &value);
798 if (!W_ERROR_IS_OK(result))
799 goto done;
801 /* Display printer data */
803 fstrcpy(value.valuename, valuename);
804 display_reg_value(value);
807 done:
808 if (opened_hnd)
809 cli_spoolss_close_printer(cli, mem_ctx, &pol);
811 return result;
814 /****************************************************************************
815 printer info level 0 display function
816 ****************************************************************************/
817 static void display_print_driver_1(DRIVER_INFO_1 *i1)
819 fstring name;
820 if (i1 == NULL)
821 return;
823 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
825 printf ("Printer Driver Info 1:\n");
826 printf ("\tDriver Name: [%s]\n\n", name);
828 return;
831 /****************************************************************************
832 printer info level 1 display function
833 ****************************************************************************/
834 static void display_print_driver_2(DRIVER_INFO_2 *i1)
836 fstring name;
837 fstring architecture;
838 fstring driverpath;
839 fstring datafile;
840 fstring configfile;
841 if (i1 == NULL)
842 return;
844 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
845 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
846 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
847 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
848 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
850 printf ("Printer Driver Info 2:\n");
851 printf ("\tVersion: [%x]\n", i1->version);
852 printf ("\tDriver Name: [%s]\n", name);
853 printf ("\tArchitecture: [%s]\n", architecture);
854 printf ("\tDriver Path: [%s]\n", driverpath);
855 printf ("\tDatafile: [%s]\n", datafile);
856 printf ("\tConfigfile: [%s]\n\n", configfile);
858 return;
861 /****************************************************************************
862 printer info level 2 display function
863 ****************************************************************************/
864 static void display_print_driver_3(DRIVER_INFO_3 *i1)
866 fstring name = "";
867 fstring architecture = "";
868 fstring driverpath = "";
869 fstring datafile = "";
870 fstring configfile = "";
871 fstring helpfile = "";
872 fstring dependentfiles = "";
873 fstring monitorname = "";
874 fstring defaultdatatype = "";
876 int length=0;
877 BOOL valid = True;
879 if (i1 == NULL)
880 return;
882 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
883 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
884 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
885 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
886 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
887 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
888 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
889 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
891 printf ("Printer Driver Info 3:\n");
892 printf ("\tVersion: [%x]\n", i1->version);
893 printf ("\tDriver Name: [%s]\n",name);
894 printf ("\tArchitecture: [%s]\n", architecture);
895 printf ("\tDriver Path: [%s]\n", driverpath);
896 printf ("\tDatafile: [%s]\n", datafile);
897 printf ("\tConfigfile: [%s]\n", configfile);
898 printf ("\tHelpfile: [%s]\n\n", helpfile);
900 while (valid)
902 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
904 length+=strlen(dependentfiles)+1;
906 if (strlen(dependentfiles) > 0)
908 printf ("\tDependentfiles: [%s]\n", dependentfiles);
910 else
912 valid = False;
916 printf ("\n");
918 printf ("\tMonitorname: [%s]\n", monitorname);
919 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
921 return;
924 /***********************************************************************
925 * Get printer information
927 static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
928 TALLOC_CTX *mem_ctx,
929 int argc, const char **argv)
931 POLICY_HND pol;
932 WERROR werror;
933 uint32 info_level = 3;
934 BOOL opened_hnd = False;
935 PRINTER_DRIVER_CTR ctr;
936 fstring printername,
937 servername,
938 user;
939 uint32 i;
940 BOOL success = False;
942 if ((argc == 1) || (argc > 3))
944 printf("Usage: %s <printername> [level]\n", argv[0]);
945 return WERR_OK;
948 /* get the arguments need to open the printer handle */
949 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
950 strupper_m(servername);
951 fstrcpy(user, cli->user_name);
952 fstrcpy(printername, argv[1]);
953 if (argc == 3)
954 info_level = atoi(argv[2]);
956 /* Open a printer handle */
958 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
959 PRINTER_ACCESS_USE,
960 servername, user, &pol);
962 if (!W_ERROR_IS_OK(werror)) {
963 printf("Error opening printer handle for %s!\n", printername);
964 return werror;
967 opened_hnd = True;
969 /* loop through and print driver info level for each architecture */
971 for (i=0; archi_table[i].long_archi!=NULL; i++) {
972 uint32 needed;
974 werror = cli_spoolss_getprinterdriver(
975 cli, mem_ctx, 0, &needed, &pol, info_level,
976 archi_table[i].long_archi, archi_table[i].version,
977 &ctr);
979 if (W_ERROR_V(werror) == ERRinsufficientbuffer) {
980 werror = cli_spoolss_getprinterdriver(
981 cli, mem_ctx, needed, NULL, &pol, info_level,
982 archi_table[i].long_archi, archi_table[i].version,
983 &ctr);
986 if (!W_ERROR_IS_OK(werror))
987 continue;
989 /* need at least one success */
991 success = True;
993 printf ("\n[%s]\n", archi_table[i].long_archi);
995 switch (info_level) {
996 case 1:
997 display_print_driver_1 (ctr.info1);
998 break;
999 case 2:
1000 display_print_driver_2 (ctr.info2);
1001 break;
1002 case 3:
1003 display_print_driver_3 (ctr.info3);
1004 break;
1005 default:
1006 printf("unknown info level %d\n", info_level);
1007 break;
1011 /* Cleanup */
1013 if (opened_hnd)
1014 cli_spoolss_close_printer (cli, mem_ctx, &pol);
1016 if ( success )
1017 werror = WERR_OK;
1019 return werror;
1022 /***********************************************************************
1023 * Get printer information
1025 static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
1026 TALLOC_CTX *mem_ctx,
1027 int argc, const char **argv)
1029 WERROR werror;
1030 uint32 info_level = 1;
1031 PRINTER_DRIVER_CTR ctr;
1032 uint32 i, j,
1033 returned;
1035 if (argc > 2)
1037 printf("Usage: enumdrivers [level]\n");
1038 return WERR_OK;
1041 if (argc == 2)
1042 info_level = atoi(argv[1]);
1045 /* loop through and print driver info level for each architecture */
1046 for (i=0; archi_table[i].long_archi!=NULL; i++)
1048 uint32 needed;
1050 werror = cli_spoolss_enumprinterdrivers(
1051 cli, mem_ctx, 0, &needed, info_level,
1052 archi_table[i].long_archi, &returned, &ctr);
1054 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1055 werror = cli_spoolss_enumprinterdrivers(
1056 cli, mem_ctx, needed, NULL, info_level,
1057 archi_table[i].long_archi, &returned, &ctr);
1059 if (returned == 0)
1060 continue;
1062 if (!W_ERROR_IS_OK(werror)) {
1063 printf ("Error getting driver for environment [%s] - %d\n",
1064 archi_table[i].long_archi, W_ERROR_V(werror));
1065 continue;
1068 printf ("\n[%s]\n", archi_table[i].long_archi);
1069 switch (info_level)
1072 case 1:
1073 for (j=0; j < returned; j++) {
1074 display_print_driver_1 (&(ctr.info1[j]));
1076 break;
1077 case 2:
1078 for (j=0; j < returned; j++) {
1079 display_print_driver_2 (&(ctr.info2[j]));
1081 break;
1082 case 3:
1083 for (j=0; j < returned; j++) {
1084 display_print_driver_3 (&(ctr.info3[j]));
1086 break;
1087 default:
1088 printf("unknown info level %d\n", info_level);
1089 break;
1093 return werror;
1096 /****************************************************************************
1097 printer info level 1 display function
1098 ****************************************************************************/
1099 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1101 fstring name;
1102 if (i1 == NULL)
1103 return;
1105 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1107 printf ("\tDirectory Name:[%s]\n", name);
1110 /***********************************************************************
1111 * Get printer driver directory information
1113 static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
1114 TALLOC_CTX *mem_ctx,
1115 int argc, const char **argv)
1117 WERROR result;
1118 fstring env;
1119 DRIVER_DIRECTORY_CTR ctr;
1120 uint32 needed;
1122 if (argc > 2) {
1123 printf("Usage: %s [environment]\n", argv[0]);
1124 return WERR_OK;
1127 /* Get the arguments need to open the printer handle */
1129 if (argc == 2)
1130 fstrcpy (env, argv[1]);
1131 else
1132 fstrcpy (env, "Windows NT x86");
1134 /* Get the directory. Only use Info level 1 */
1136 result = cli_spoolss_getprinterdriverdir(
1137 cli, mem_ctx, 0, &needed, 1, env, &ctr);
1139 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1140 result = cli_spoolss_getprinterdriverdir(
1141 cli, mem_ctx, needed, NULL, 1, env, &ctr);
1143 if (W_ERROR_IS_OK(result))
1144 display_printdriverdir_1(ctr.info1);
1146 return result;
1149 /*******************************************************************************
1150 set the version and environment fields of a DRIVER_INFO_3 struct
1151 ******************************************************************************/
1152 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1155 int i;
1157 for (i=0; archi_table[i].long_archi != NULL; i++)
1159 if (strcmp(arch, archi_table[i].short_archi) == 0)
1161 info->version = archi_table[i].version;
1162 init_unistr (&info->architecture, archi_table[i].long_archi);
1163 break;
1167 if (archi_table[i].long_archi == NULL)
1169 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1172 return;
1176 /**************************************************************************
1177 wrapper for strtok to get the next parameter from a delimited list.
1178 Needed to handle the empty parameter string denoted by "NULL"
1179 *************************************************************************/
1180 static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
1182 char *ptr;
1184 /* get the next token */
1185 ptr = strtok(str, delim);
1187 /* a string of 'NULL' is used to represent an empty
1188 parameter because two consecutive delimiters
1189 will not return an empty string. See man strtok(3)
1190 for details */
1191 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
1192 ptr = NULL;
1194 if (dest != NULL)
1195 init_unistr(dest, ptr);
1197 return ptr;
1200 /********************************************************************************
1201 fill in the members of a DRIVER_INFO_3 struct using a character
1202 string in the form of
1203 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1204 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1205 <Default Data Type>:<Comma Separated list of Files>
1206 *******************************************************************************/
1207 static BOOL init_drv_info_3_members (
1208 TALLOC_CTX *mem_ctx,
1209 DRIVER_INFO_3 *info,
1210 const char *args
1213 char *str, *str2;
1214 uint32 len, i;
1216 /* fill in the UNISTR fields */
1217 str = get_driver_3_param (args, ":", &info->name);
1218 str = get_driver_3_param (NULL, ":", &info->driverpath);
1219 str = get_driver_3_param (NULL, ":", &info->datafile);
1220 str = get_driver_3_param (NULL, ":", &info->configfile);
1221 str = get_driver_3_param (NULL, ":", &info->helpfile);
1222 str = get_driver_3_param (NULL, ":", &info->monitorname);
1223 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1225 /* <Comma Separated List of Dependent Files> */
1226 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1227 str = str2;
1229 /* begin to strip out each filename */
1230 str = strtok(str, ",");
1231 len = 0;
1232 while (str != NULL)
1234 /* keep a cumlative count of the str lengths */
1235 len += strlen(str)+1;
1236 str = strtok(NULL, ",");
1239 /* allocate the space; add one extra slot for a terminating NULL.
1240 Each filename is NULL terminated and the end contains a double
1241 NULL */
1242 if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL)
1244 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1245 return False;
1247 for (i=0; i<len; i++)
1249 SSVAL(&info->dependentfiles[i], 0, str2[i]);
1251 info->dependentfiles[len] = '\0';
1253 return True;
1257 static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
1258 TALLOC_CTX *mem_ctx,
1259 int argc, const char **argv)
1261 WERROR result;
1262 uint32 level = 3;
1263 PRINTER_DRIVER_CTR ctr;
1264 DRIVER_INFO_3 info3;
1265 const char *arch;
1266 fstring driver_name;
1268 /* parse the command arguements */
1269 if (argc != 3 && argc != 4)
1271 printf ("Usage: %s <Environment> \\\n", argv[0]);
1272 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1273 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1274 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1275 printf ("\t[version]\n");
1277 return WERR_OK;
1280 /* Fill in the DRIVER_INFO_3 struct */
1281 ZERO_STRUCT(info3);
1282 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
1284 printf ("Error Unknown architechture [%s]\n", argv[1]);
1285 return WERR_INVALID_PARAM;
1287 else
1288 set_drv_info_3_env(&info3, arch);
1290 if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
1292 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1293 return WERR_INVALID_PARAM;
1296 /* if printer driver version specified, override the default version
1297 * used by the architecture. This allows installation of Windows
1298 * 2000 (version 3) printer drivers. */
1299 if (argc == 4)
1301 info3.version = atoi(argv[3]);
1305 ctr.info3 = &info3;
1306 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1308 if (W_ERROR_IS_OK(result)) {
1309 rpcstr_pull(driver_name, info3.name.buffer,
1310 sizeof(driver_name), -1, STR_TERMINATE);
1311 printf ("Printer Driver %s successfully installed.\n",
1312 driver_name);
1315 return result;
1319 static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
1320 TALLOC_CTX *mem_ctx,
1321 int argc, const char **argv)
1323 WERROR result;
1324 uint32 level = 2;
1325 PRINTER_INFO_CTR ctr;
1326 PRINTER_INFO_2 info2;
1327 fstring servername;
1329 /* parse the command arguements */
1330 if (argc != 5)
1332 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1333 return WERR_OK;
1336 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1337 strupper_m(servername);
1339 /* Fill in the DRIVER_INFO_2 struct */
1340 ZERO_STRUCT(info2);
1341 #if 0 /* JERRY */
1342 init_unistr( &info2.servername, servername);
1343 #endif
1344 init_unistr( &info2.printername, argv[1]);
1345 init_unistr( &info2.sharename, argv[2]);
1346 init_unistr( &info2.drivername, argv[3]);
1347 init_unistr( &info2.portname, argv[4]);
1348 init_unistr( &info2.comment, "Created by rpcclient");
1349 init_unistr( &info2.printprocessor, "winprint");
1350 init_unistr( &info2.datatype, "RAW");
1351 info2.devmode = NULL;
1352 info2.secdesc = NULL;
1353 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1354 info2.priority = 0;
1355 info2.defaultpriority = 0;
1356 info2.starttime = 0;
1357 info2.untiltime = 0;
1359 /* These three fields must not be used by AddPrinter()
1360 as defined in the MS Platform SDK documentation..
1361 --jerry
1362 info2.status = 0;
1363 info2.cjobs = 0;
1364 info2.averageppm = 0;
1367 ctr.printers_2 = &info2;
1368 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1370 if (W_ERROR_IS_OK(result))
1371 printf ("Printer %s successfully installed.\n", argv[1]);
1373 return result;
1376 static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
1377 TALLOC_CTX *mem_ctx,
1378 int argc, const char **argv)
1380 POLICY_HND pol;
1381 WERROR result;
1382 uint32 level = 2;
1383 BOOL opened_hnd = False;
1384 PRINTER_INFO_CTR ctr;
1385 PRINTER_INFO_2 info2;
1386 fstring servername,
1387 printername,
1388 user;
1389 uint32 needed;
1391 /* parse the command arguements */
1392 if (argc != 3)
1394 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1395 return WERR_OK;
1398 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1399 strupper_m(servername);
1400 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1401 fstrcpy(user, cli->user_name);
1403 /* Get a printer handle */
1405 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1406 PRINTER_ALL_ACCESS,
1407 servername, user, &pol);
1409 if (!W_ERROR_IS_OK(result))
1410 goto done;
1412 opened_hnd = True;
1414 /* Get printer info */
1416 ZERO_STRUCT (info2);
1417 ctr.printers_2 = &info2;
1419 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1420 &pol, level, &ctr);
1422 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1423 result = cli_spoolss_getprinter(
1424 cli, mem_ctx, needed, NULL, &pol, level, &ctr);
1426 if (!W_ERROR_IS_OK(result)) {
1427 printf ("Unable to retrieve printer information!\n");
1428 goto done;
1431 /* Set the printer driver */
1433 init_unistr(&ctr.printers_2->drivername, argv[2]);
1435 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1437 if (!W_ERROR_IS_OK(result)) {
1438 printf("SetPrinter call failed!\n");
1439 goto done;;
1442 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1444 done:
1445 /* Cleanup */
1447 if (opened_hnd)
1448 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1450 return result;
1454 static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
1455 TALLOC_CTX *mem_ctx,
1456 int argc, const char **argv)
1458 WERROR result;
1459 fstring servername;
1460 int i;
1462 /* parse the command arguements */
1463 if (argc != 2)
1465 printf ("Usage: %s <driver>\n", argv[0]);
1466 return WERR_OK;
1469 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1470 strupper_m(servername);
1472 /* delete the driver for all architectures */
1473 for (i=0; archi_table[i].long_archi; i++)
1475 /* make the call to remove the driver */
1476 result = cli_spoolss_deleteprinterdriver(
1477 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1479 if ( !W_ERROR_IS_OK(result) ) {
1480 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1481 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1482 argv[1], archi_table[i].long_archi,
1483 W_ERROR_V(result));
1486 else
1488 printf ("Driver %s removed for arch [%s].\n", argv[1],
1489 archi_table[i].long_archi);
1493 return result;
1496 static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
1497 TALLOC_CTX *mem_ctx,
1498 int argc, const char **argv)
1500 WERROR result;
1501 char *servername = NULL, *environment = NULL;
1502 fstring procdir;
1503 uint32 needed;
1505 /* parse the command arguements */
1506 if (argc > 2) {
1507 printf ("Usage: %s [environment]\n", argv[0]);
1508 return WERR_OK;
1511 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1512 return WERR_NOMEM;
1513 strupper_m(servername);
1515 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1516 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1517 SAFE_FREE(servername);
1518 return WERR_NOMEM;
1521 result = cli_spoolss_getprintprocessordirectory(
1522 cli, mem_ctx, 0, &needed, servername, environment, procdir);
1524 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1525 result = cli_spoolss_getprintprocessordirectory(
1526 cli, mem_ctx, needed, NULL, servername, environment,
1527 procdir);
1529 if (W_ERROR_IS_OK(result))
1530 printf("%s\n", procdir);
1532 SAFE_FREE(servername);
1533 SAFE_FREE(environment);
1535 return result;
1538 /* Add a form */
1540 static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1541 int argc, const char **argv)
1543 POLICY_HND handle;
1544 WERROR werror;
1545 char *servername = NULL, *printername = NULL;
1546 FORM form;
1547 BOOL got_handle = False;
1549 /* Parse the command arguements */
1551 if (argc != 3) {
1552 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1553 return WERR_OK;
1556 /* Get a printer handle */
1558 asprintf(&servername, "\\\\%s", cli->desthost);
1559 strupper_m(servername);
1560 asprintf(&printername, "%s\\%s", servername, argv[1]);
1562 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1563 MAXIMUM_ALLOWED_ACCESS,
1564 servername, cli->user_name, &handle);
1566 if (!W_ERROR_IS_OK(werror))
1567 goto done;
1569 got_handle = True;
1571 /* Dummy up some values for the form data */
1573 form.flags = FORM_USER;
1574 form.size_x = form.size_y = 100;
1575 form.left = 0;
1576 form.top = 10;
1577 form.right = 20;
1578 form.bottom = 30;
1580 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1582 /* Add the form */
1585 werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1587 done:
1588 if (got_handle)
1589 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1591 SAFE_FREE(servername);
1592 SAFE_FREE(printername);
1594 return werror;
1597 /* Set a form */
1599 static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1600 int argc, const char **argv)
1602 POLICY_HND handle;
1603 WERROR werror;
1604 char *servername = NULL, *printername = NULL;
1605 FORM form;
1606 BOOL got_handle = False;
1608 /* Parse the command arguements */
1610 if (argc != 3) {
1611 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1612 return WERR_OK;
1615 /* Get a printer handle */
1617 asprintf(&servername, "\\\\%s", cli->desthost);
1618 strupper_m(servername);
1619 asprintf(&printername, "%s\\%s", servername, argv[1]);
1621 werror = cli_spoolss_open_printer_ex(
1622 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1623 servername, cli->user_name, &handle);
1625 if (!W_ERROR_IS_OK(werror))
1626 goto done;
1628 got_handle = True;
1630 /* Dummy up some values for the form data */
1632 form.flags = FORM_PRINTER;
1633 form.size_x = form.size_y = 100;
1634 form.left = 0;
1635 form.top = 1000;
1636 form.right = 2000;
1637 form.bottom = 3000;
1639 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1641 /* Set the form */
1643 werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1645 done:
1646 if (got_handle)
1647 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1649 SAFE_FREE(servername);
1650 SAFE_FREE(printername);
1652 return werror;
1655 /* Get a form */
1657 static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1658 int argc, const char **argv)
1660 POLICY_HND handle;
1661 WERROR werror;
1662 char *servername = NULL, *printername = NULL;
1663 FORM_1 form;
1664 BOOL got_handle = False;
1665 uint32 needed;
1667 /* Parse the command arguements */
1669 if (argc != 3) {
1670 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1671 return WERR_OK;
1674 /* Get a printer handle */
1676 asprintf(&servername, "\\\\%s", cli->desthost);
1677 strupper_m(servername);
1678 asprintf(&printername, "%s\\%s", servername, argv[1]);
1680 werror = cli_spoolss_open_printer_ex(
1681 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1682 servername, cli->user_name, &handle);
1684 if (!W_ERROR_IS_OK(werror))
1685 goto done;
1687 got_handle = True;
1689 /* Set the form */
1691 werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
1692 &handle, argv[2], 1, &form);
1694 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1695 werror = cli_spoolss_getform(cli, mem_ctx, needed, NULL,
1696 &handle, argv[2], 1, &form);
1698 if (!W_ERROR_IS_OK(werror))
1699 goto done;
1701 printf("width: %d\n", form.width);
1702 printf("length: %d\n", form.length);
1703 printf("left: %d\n", form.left);
1704 printf("top: %d\n", form.top);
1705 printf("right: %d\n", form.right);
1706 printf("bottom: %d\n", form.bottom);
1708 done:
1709 if (got_handle)
1710 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1712 SAFE_FREE(servername);
1713 SAFE_FREE(printername);
1715 return werror;
1718 /* Delete a form */
1720 static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
1721 TALLOC_CTX *mem_ctx, int argc,
1722 const char **argv)
1724 POLICY_HND handle;
1725 WERROR werror;
1726 char *servername = NULL, *printername = NULL;
1727 BOOL got_handle = False;
1729 /* Parse the command arguements */
1731 if (argc != 3) {
1732 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1733 return WERR_OK;
1736 /* Get a printer handle */
1738 asprintf(&servername, "\\\\%s", cli->desthost);
1739 strupper_m(servername);
1740 asprintf(&printername, "%s\\%s", servername, argv[1]);
1742 werror = cli_spoolss_open_printer_ex(
1743 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1744 servername, cli->user_name, &handle);
1746 if (!W_ERROR_IS_OK(werror))
1747 goto done;
1749 got_handle = True;
1751 /* Delete the form */
1753 werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1755 done:
1756 if (got_handle)
1757 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1759 SAFE_FREE(servername);
1760 SAFE_FREE(printername);
1762 return werror;
1765 /* Enumerate forms */
1767 static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
1768 TALLOC_CTX *mem_ctx, int argc,
1769 const char **argv)
1771 POLICY_HND handle;
1772 WERROR werror;
1773 char *servername = NULL, *printername = NULL;
1774 BOOL got_handle = False;
1775 uint32 needed, num_forms, level = 1, i;
1776 FORM_1 *forms;
1778 /* Parse the command arguements */
1780 if (argc != 2) {
1781 printf ("Usage: %s <printer>\n", argv[0]);
1782 return WERR_OK;
1785 /* Get a printer handle */
1787 asprintf(&servername, "\\\\%s", cli->desthost);
1788 strupper_m(servername);
1789 asprintf(&printername, "%s\\%s", servername, argv[1]);
1791 werror = cli_spoolss_open_printer_ex(
1792 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1793 servername, cli->user_name, &handle);
1795 if (!W_ERROR_IS_OK(werror))
1796 goto done;
1798 got_handle = True;
1800 /* Enumerate forms */
1802 werror = cli_spoolss_enumforms(
1803 cli, mem_ctx, 0, &needed, &handle, level, &num_forms, &forms);
1805 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
1806 werror = cli_spoolss_enumforms(
1807 cli, mem_ctx, needed, NULL, &handle, level,
1808 &num_forms, &forms);
1810 if (!W_ERROR_IS_OK(werror))
1811 goto done;
1813 /* Display output */
1815 for (i = 0; i < num_forms; i++) {
1816 fstring form_name;
1818 if (forms[i].name.buffer)
1819 rpcstr_pull(form_name, forms[i].name.buffer,
1820 sizeof(form_name), -1, STR_TERMINATE);
1822 printf("%s\n", form_name);
1825 done:
1826 if (got_handle)
1827 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1829 SAFE_FREE(servername);
1830 SAFE_FREE(printername);
1832 return werror;
1835 static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
1836 TALLOC_CTX *mem_ctx,
1837 int argc, const char **argv)
1839 WERROR result;
1840 uint32 needed;
1841 fstring servername, printername, user;
1842 POLICY_HND pol;
1843 BOOL opened_hnd = False;
1844 PRINTER_INFO_CTR ctr;
1845 PRINTER_INFO_0 info;
1846 REGISTRY_VALUE value;
1848 /* parse the command arguements */
1849 if (argc != 4) {
1850 printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
1851 return WERR_OK;
1854 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1855 strupper_m(servername);
1856 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1857 fstrcpy(user, cli->user_name);
1859 /* get a printer handle */
1860 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1861 MAXIMUM_ALLOWED_ACCESS, servername,
1862 user, &pol);
1863 if (!W_ERROR_IS_OK(result))
1864 goto done;
1866 opened_hnd = True;
1868 ctr.printers_0 = &info;
1870 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
1871 &pol, 0, &ctr);
1873 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1874 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1876 if (!W_ERROR_IS_OK(result))
1877 goto done;
1879 printf("%s\n", timestring(True));
1880 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
1882 /* Set the printer data */
1884 fstrcpy(value.valuename, argv[2]);
1885 value.type = REG_SZ;
1886 value.size = strlen(argv[3]) + 1;
1887 value.data_p = talloc_memdup(mem_ctx, argv[3], value.size);
1889 result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
1891 if (!W_ERROR_IS_OK(result)) {
1892 printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
1893 goto done;
1895 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
1897 result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, 0, &ctr);
1899 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1900 result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
1902 if (!W_ERROR_IS_OK(result))
1903 goto done;
1905 printf("%s\n", timestring(True));
1906 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
1908 done:
1909 /* cleanup */
1910 if (opened_hnd)
1911 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1913 return result;
1916 static void display_job_info_1(JOB_INFO_1 *job)
1918 fstring username = "", document = "", text_status = "";
1920 rpcstr_pull(username, job->username.buffer,
1921 sizeof(username), -1, STR_TERMINATE);
1923 rpcstr_pull(document, job->document.buffer,
1924 sizeof(document), -1, STR_TERMINATE);
1926 rpcstr_pull(text_status, job->text_status.buffer,
1927 sizeof(text_status), -1, STR_TERMINATE);
1929 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
1930 username, document, text_status, job->pagesprinted,
1931 job->totalpages);
1934 static void display_job_info_2(JOB_INFO_2 *job)
1936 fstring username = "", document = "", text_status = "";
1938 rpcstr_pull(username, job->username.buffer,
1939 sizeof(username), -1, STR_TERMINATE);
1941 rpcstr_pull(document, job->document.buffer,
1942 sizeof(document), -1, STR_TERMINATE);
1944 rpcstr_pull(text_status, job->text_status.buffer,
1945 sizeof(text_status), -1, STR_TERMINATE);
1947 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
1948 username, document, text_status, job->pagesprinted,
1949 job->totalpages, job->size);
1952 /* Enumerate jobs */
1954 static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
1955 TALLOC_CTX *mem_ctx, int argc,
1956 const char **argv)
1958 WERROR result;
1959 uint32 needed, level = 1, num_jobs, i;
1960 BOOL got_hnd = False;
1961 pstring printername;
1962 fstring servername, user;
1963 POLICY_HND hnd;
1964 JOB_INFO_CTR ctr;
1966 if (argc < 2 || argc > 3) {
1967 printf("Usage: %s printername [level]\n", argv[0]);
1968 return WERR_OK;
1971 if (argc == 3)
1972 level = atoi(argv[2]);
1974 /* Open printer handle */
1976 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1977 strupper_m(servername);
1978 fstrcpy(user, cli->user_name);
1979 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
1980 strupper_m(printername);
1981 pstrcat(printername, argv[1]);
1983 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
1984 "", MAXIMUM_ALLOWED_ACCESS,
1985 servername, user, &hnd);
1987 if (!W_ERROR_IS_OK(result))
1988 goto done;
1990 got_hnd = True;
1992 /* Enumerate ports */
1994 result = cli_spoolss_enumjobs(
1995 cli, mem_ctx, 0, &needed, &hnd, level, 0, 1000,
1996 &num_jobs, &ctr);
1998 if (W_ERROR_V(result) == ERRinsufficientbuffer)
1999 result = cli_spoolss_enumjobs(
2000 cli, mem_ctx, needed, NULL, &hnd, level, 0,
2001 1000, &num_jobs, &ctr);
2003 if (!W_ERROR_IS_OK(result))
2004 goto done;
2006 for (i = 0; i < num_jobs; i++) {
2007 switch(level) {
2008 case 1:
2009 display_job_info_1(&ctr.job.job_info_1[i]);
2010 break;
2011 case 2:
2012 display_job_info_2(&ctr.job.job_info_2[i]);
2013 break;
2014 default:
2015 d_printf("unknown info level %d\n", level);
2016 break;
2020 done:
2021 if (got_hnd)
2022 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2024 return result;
2027 /* enumerate data */
2029 static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
2030 TALLOC_CTX *mem_ctx, int argc,
2031 const char **argv)
2033 WERROR result;
2034 uint32 i=0, val_needed, data_needed;
2035 BOOL got_hnd = False;
2036 pstring printername;
2037 fstring servername, user;
2038 POLICY_HND hnd;
2040 if (argc != 2) {
2041 printf("Usage: %s printername\n", argv[0]);
2042 return WERR_OK;
2045 /* Open printer handle */
2047 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2048 strupper_m(servername);
2049 fstrcpy(user, cli->user_name);
2050 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2051 strupper_m(printername);
2052 pstrcat(printername, argv[1]);
2054 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2055 "", MAXIMUM_ALLOWED_ACCESS,
2056 servername, user, &hnd);
2058 if (!W_ERROR_IS_OK(result))
2059 goto done;
2061 got_hnd = True;
2063 /* Enumerate data */
2065 result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2066 &val_needed, &data_needed,
2067 NULL);
2068 while (W_ERROR_IS_OK(result)) {
2069 REGISTRY_VALUE value;
2070 result = cli_spoolss_enumprinterdata(
2071 cli, mem_ctx, &hnd, i++, val_needed,
2072 data_needed, 0, 0, &value);
2073 if (W_ERROR_IS_OK(result))
2074 display_reg_value(value);
2076 if (W_ERROR_V(result) == ERRnomoreitems)
2077 result = W_ERROR(ERRsuccess);
2079 done:
2080 if (got_hnd)
2081 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2083 return result;
2086 /* enumerate data for a given key */
2088 static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
2089 TALLOC_CTX *mem_ctx, int argc,
2090 const char **argv)
2092 WERROR result;
2093 uint32 needed, i;
2094 BOOL got_hnd = False;
2095 pstring printername;
2096 fstring servername, user;
2097 const char *keyname = NULL;
2098 POLICY_HND hnd;
2099 REGVAL_CTR ctr;
2101 if (argc != 3) {
2102 printf("Usage: %s printername <keyname>\n", argv[0]);
2103 return WERR_OK;
2106 keyname = argv[2];
2108 /* Open printer handle */
2110 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2111 strupper_m(servername);
2112 fstrcpy(user, cli->user_name);
2113 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2114 strupper_m(printername);
2115 pstrcat(printername, argv[1]);
2117 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2118 "", MAXIMUM_ALLOWED_ACCESS,
2119 servername, user, &hnd);
2121 if (!W_ERROR_IS_OK(result))
2122 goto done;
2124 got_hnd = True;
2126 /* Enumerate subkeys */
2128 result = cli_spoolss_enumprinterdataex(
2129 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL);
2131 if (W_ERROR_V(result) == ERRmoredata)
2132 result = cli_spoolss_enumprinterdataex(
2133 cli, mem_ctx, needed, NULL, &hnd, keyname, &ctr);
2135 if (!W_ERROR_IS_OK(result))
2136 goto done;
2138 for (i=0; i < ctr.num_values; i++) {
2139 display_reg_value(*(ctr.values[i]));
2142 regval_ctr_destroy(&ctr);
2144 done:
2145 if (got_hnd)
2146 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2148 return result;
2151 /* enumerate subkeys */
2153 static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
2154 TALLOC_CTX *mem_ctx, int argc,
2155 const char **argv)
2157 WERROR result;
2158 uint32 needed, returned;
2159 BOOL got_hnd = False;
2160 pstring printername;
2161 fstring servername, user;
2162 const char *keyname = NULL;
2163 POLICY_HND hnd;
2164 uint16 *keylist = NULL, *curkey;
2166 if (argc < 2 || argc > 3) {
2167 printf("Usage: %s printername [keyname]\n", argv[0]);
2168 return WERR_OK;
2171 if (argc == 3)
2172 keyname = argv[2];
2173 else
2174 keyname = "";
2176 /* Open printer handle */
2178 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2179 strupper_m(servername);
2180 fstrcpy(user, cli->user_name);
2181 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2182 strupper_m(printername);
2183 pstrcat(printername, argv[1]);
2185 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2186 "", MAXIMUM_ALLOWED_ACCESS,
2187 servername, user, &hnd);
2189 if (!W_ERROR_IS_OK(result))
2190 goto done;
2192 got_hnd = True;
2194 /* Enumerate subkeys */
2196 result = cli_spoolss_enumprinterkey(
2197 cli, mem_ctx, 0, &needed, &hnd, keyname, NULL, NULL);
2199 if (W_ERROR_V(result) == ERRmoredata)
2200 result = cli_spoolss_enumprinterkey(
2201 cli, mem_ctx, needed, NULL, &hnd, keyname, &keylist,
2202 &returned);
2204 if (!W_ERROR_IS_OK(result))
2205 goto done;
2207 curkey = keylist;
2208 while (*curkey != 0) {
2209 pstring subkey;
2210 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2211 STR_TERMINATE);
2212 printf("%s\n", subkey);
2213 curkey += strlen(subkey) + 1;
2216 safe_free(keylist);
2218 done:
2219 if (got_hnd)
2220 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2222 return result;
2225 static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
2226 TALLOC_CTX *mem_ctx, int argc,
2227 const char **argv)
2229 fstring servername, printername;
2230 POLICY_HND hnd;
2231 BOOL got_hnd = False;
2232 WERROR result;
2233 SPOOL_NOTIFY_OPTION option;
2235 if (argc != 2) {
2236 printf("Usage: %s printername\n", argv[0]);
2237 result = WERR_OK;
2238 goto done;
2241 /* Open printer */
2243 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2244 strupper_m(servername);
2246 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
2247 argv[1]);
2248 strupper_m(printername);
2250 result = cli_spoolss_open_printer_ex(
2251 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2252 servername, cli->user_name, &hnd);
2254 if (!W_ERROR_IS_OK(result)) {
2255 printf("Error opening %s\n", argv[1]);
2256 goto done;
2259 got_hnd = True;
2261 /* Create spool options */
2263 ZERO_STRUCT(option);
2265 option.version = 2;
2266 option.option_type_ptr = 1;
2267 option.count = option.ctr.count = 2;
2269 option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc(
2270 mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2);
2272 ZERO_STRUCT(option.ctr.type[0]);
2273 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2274 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2275 option.ctr.type[0].fields_ptr = 1;
2276 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2278 ZERO_STRUCT(option.ctr.type[1]);
2279 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2280 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2281 option.ctr.type[1].fields_ptr = 1;
2282 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2284 /* Send rffpcnex */
2286 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2287 strupper_m(servername);
2289 result = cli_spoolss_rffpcnex(
2290 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2292 if (!W_ERROR_IS_OK(result)) {
2293 printf("Error rffpcnex %s\n", argv[1]);
2294 goto done;
2297 done:
2298 if (got_hnd)
2299 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2301 return result;
2304 /* List of commands exported by this module */
2305 struct cmd_set spoolss_commands[] = {
2307 { "SPOOLSS" },
2309 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
2310 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
2311 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
2312 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
2313 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
2314 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
2315 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
2316 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
2317 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
2318 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
2319 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
2320 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
2321 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
2322 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
2323 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
2324 { "getprintprocdir",RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2325 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
2326 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
2327 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2328 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
2329 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
2330 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
2331 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
2332 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
2333 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
2334 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
2335 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },
2337 { NULL }