r8654: merging cli_spoolss_XX() updates from trunk
[Samba.git] / source / rpcclient / cmd_spoolss.c
blobf774d408fe6628e6cb8d4c8ddfa75468f9816dca
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
5 Copyright (C) Gerald Carter 2001-2005
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 /* The version int is used by getdrivers. Note that
35 all architecture strings that support mutliple
36 versions must be grouped together since enumdrivers
37 uses this property to prevent issuing multiple
38 enumdriver calls for the same arch */
41 static const struct table_node archi_table[]= {
43 {"Windows 4.0", "WIN40", 0 },
44 {"Windows NT x86", "W32X86", 2 },
45 {"Windows NT x86", "W32X86", 3 },
46 {"Windows NT R4000", "W32MIPS", 2 },
47 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
48 {"Windows NT PowerPC", "W32PPC", 2 },
49 {"Windows IA64", "IA64", 3 },
50 {"Windows x64", "x64", 3 },
51 {NULL, "", -1 }
54 /**
55 * @file
57 * rpcclient module for SPOOLSS rpc pipe.
59 * This generally just parses and checks command lines, and then calls
60 * a cli_spoolss function.
61 **/
63 /****************************************************************************
64 function to do the mapping between the long architecture name and
65 the short one.
66 ****************************************************************************/
68 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
70 int i=-1;
72 DEBUG(107,("Getting architecture dependant directory\n"));
73 do {
74 i++;
75 } while ( (archi_table[i].long_archi!=NULL ) &&
76 StrCaseCmp(long_archi, archi_table[i].long_archi) );
78 if (archi_table[i].long_archi==NULL) {
79 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
80 return NULL;
83 /* this might be client code - but shouldn't this be an fstrcpy etc? */
86 DEBUGADD(108,("index: [%d]\n", i));
87 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
88 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
90 return archi_table[i].short_archi;
93 /****************************************************************************
94 ****************************************************************************/
96 static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
97 TALLOC_CTX *mem_ctx,
98 int argc, const char **argv)
100 WERROR werror;
101 fstring printername;
102 fstring servername, user;
103 POLICY_HND hnd;
105 if (argc != 2) {
106 printf("Usage: %s <printername>\n", argv[0]);
107 return WERR_OK;
110 if (!cli)
111 return WERR_GENERAL_FAILURE;
113 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
114 strupper_m(servername);
115 fstrcpy(user, cli->user_name);
116 fstrcpy(printername, argv[1]);
118 /* Open the printer handle */
120 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
121 "", PRINTER_ALL_ACCESS,
122 servername, user, &hnd);
124 if (W_ERROR_IS_OK(werror)) {
125 printf("Printer %s opened successfully\n", printername);
126 werror = cli_spoolss_close_printer(cli, mem_ctx, &hnd);
128 if (!W_ERROR_IS_OK(werror)) {
129 printf("Error closing printer handle! (%s)\n",
130 get_dos_error_msg(werror));
134 return werror;
138 /****************************************************************************
139 ****************************************************************************/
141 static void display_print_info_0(PRINTER_INFO_0 *i0)
143 fstring name = "";
144 fstring servername = "";
146 if (!i0)
147 return;
149 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
151 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
153 printf("\tprintername:[%s]\n", name);
154 printf("\tservername:[%s]\n", servername);
155 printf("\tcjobs:[0x%x]\n", i0->cjobs);
156 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
158 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
159 i0->day, i0->dayofweek);
160 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
161 i0->second, i0->milliseconds);
163 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
164 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
166 printf("\tmajorversion:[0x%x]\n", i0->major_version);
167 printf("\tbuildversion:[0x%x]\n", i0->build_version);
169 printf("\tunknown7:[0x%x]\n", i0->unknown7);
170 printf("\tunknown8:[0x%x]\n", i0->unknown8);
171 printf("\tunknown9:[0x%x]\n", i0->unknown9);
172 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
173 printf("\tunknown11:[0x%x]\n", i0->unknown11);
174 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
175 printf("\tunknown13:[0x%x]\n", i0->unknown13);
176 printf("\tunknown14:[0x%x]\n", i0->unknown14);
177 printf("\tunknown15:[0x%x]\n", i0->unknown15);
178 printf("\tunknown16:[0x%x]\n", i0->unknown16);
179 printf("\tchange_id:[0x%x]\n", i0->change_id);
180 printf("\tunknown18:[0x%x]\n", i0->unknown18);
181 printf("\tstatus:[0x%x]\n", i0->status);
182 printf("\tunknown20:[0x%x]\n", i0->unknown20);
183 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
184 printf("\tunknown22:[0x%x]\n", i0->unknown22);
185 printf("\tunknown23:[0x%x]\n", i0->unknown23);
186 printf("\tunknown24:[0x%x]\n", i0->unknown24);
187 printf("\tunknown25:[0x%x]\n", i0->unknown25);
188 printf("\tunknown26:[0x%x]\n", i0->unknown26);
189 printf("\tunknown27:[0x%x]\n", i0->unknown27);
190 printf("\tunknown28:[0x%x]\n", i0->unknown28);
191 printf("\tunknown29:[0x%x]\n", i0->unknown29);
193 printf("\n");
196 /****************************************************************************
197 ****************************************************************************/
199 static void display_print_info_1(PRINTER_INFO_1 *i1)
201 fstring desc = "";
202 fstring name = "";
203 fstring comm = "";
205 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
206 STR_TERMINATE);
208 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
209 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
211 printf("\tflags:[0x%x]\n", i1->flags);
212 printf("\tname:[%s]\n", name);
213 printf("\tdescription:[%s]\n", desc);
214 printf("\tcomment:[%s]\n", comm);
216 printf("\n");
219 /****************************************************************************
220 ****************************************************************************/
222 static void display_print_info_2(PRINTER_INFO_2 *i2)
224 fstring servername = "";
225 fstring printername = "";
226 fstring sharename = "";
227 fstring portname = "";
228 fstring drivername = "";
229 fstring comment = "";
230 fstring location = "";
231 fstring sepfile = "";
232 fstring printprocessor = "";
233 fstring datatype = "";
234 fstring parameters = "";
236 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
237 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
238 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
239 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
240 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
241 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
242 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
243 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
244 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
245 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
246 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
248 printf("\tservername:[%s]\n", servername);
249 printf("\tprintername:[%s]\n", printername);
250 printf("\tsharename:[%s]\n", sharename);
251 printf("\tportname:[%s]\n", portname);
252 printf("\tdrivername:[%s]\n", drivername);
253 printf("\tcomment:[%s]\n", comment);
254 printf("\tlocation:[%s]\n", location);
255 printf("\tsepfile:[%s]\n", sepfile);
256 printf("\tprintprocessor:[%s]\n", printprocessor);
257 printf("\tdatatype:[%s]\n", datatype);
258 printf("\tparameters:[%s]\n", parameters);
259 printf("\tattributes:[0x%x]\n", i2->attributes);
260 printf("\tpriority:[0x%x]\n", i2->priority);
261 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
262 printf("\tstarttime:[0x%x]\n", i2->starttime);
263 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
264 printf("\tstatus:[0x%x]\n", i2->status);
265 printf("\tcjobs:[0x%x]\n", i2->cjobs);
266 printf("\taverageppm:[0x%x]\n", i2->averageppm);
268 if (i2->secdesc)
269 display_sec_desc(i2->secdesc);
271 printf("\n");
274 /****************************************************************************
275 ****************************************************************************/
277 static void display_print_info_3(PRINTER_INFO_3 *i3)
279 printf("\tflags:[0x%x]\n", i3->flags);
281 display_sec_desc(i3->secdesc);
283 printf("\n");
286 /****************************************************************************
287 ****************************************************************************/
289 static void display_print_info_7(PRINTER_INFO_7 *i7)
291 fstring guid = "";
292 rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE);
293 printf("\tguid:[%s]\n", guid);
294 printf("\taction:[0x%x]\n", i7->action);
298 /****************************************************************************
299 ****************************************************************************/
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;
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 ZERO_STRUCT(ctr);
329 result = cli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
330 info_level, &num_printers, &ctr);
332 if (W_ERROR_IS_OK(result)) {
334 if (!num_printers) {
335 printf ("No printers returned.\n");
336 goto done;
339 for (i = 0; i < num_printers; i++) {
340 switch(info_level) {
341 case 0:
342 display_print_info_0(&ctr.printers_0[i]);
343 break;
344 case 1:
345 display_print_info_1(&ctr.printers_1[i]);
346 break;
347 case 2:
348 display_print_info_2(&ctr.printers_2[i]);
349 break;
350 case 3:
351 display_print_info_3(&ctr.printers_3[i]);
352 break;
353 default:
354 printf("unknown info level %d\n", info_level);
355 goto done;
359 done:
361 return result;
364 /****************************************************************************
365 ****************************************************************************/
367 static void display_port_info_1(PORT_INFO_1 *i1)
369 fstring buffer;
371 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
372 printf("\tPort Name:\t[%s]\n", buffer);
375 /****************************************************************************
376 ****************************************************************************/
378 static void display_port_info_2(PORT_INFO_2 *i2)
380 fstring buffer;
382 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
383 printf("\tPort Name:\t[%s]\n", buffer);
384 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
386 printf("\tMonitor Name:\t[%s]\n", buffer);
387 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
389 printf("\tDescription:\t[%s]\n", buffer);
390 printf("\tPort Type:\t" );
391 if ( i2->port_type ) {
392 int comma = 0; /* hack */
393 printf( "[" );
394 if ( i2->port_type & PORT_TYPE_READ ) {
395 printf( "Read" );
396 comma = 1;
398 if ( i2->port_type & PORT_TYPE_WRITE ) {
399 printf( "%sWrite", comma ? ", " : "" );
400 comma = 1;
402 /* These two have slightly different interpretations
403 on 95/98/ME but I'm disregarding that for now */
404 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
405 printf( "%sRedirected", comma ? ", " : "" );
406 comma = 1;
408 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
409 printf( "%sNet-Attached", comma ? ", " : "" );
411 printf( "]\n" );
412 } else {
413 printf( "[Unset]\n" );
415 printf("\tReserved:\t[%d]\n", i2->reserved);
416 printf("\n");
419 /****************************************************************************
420 ****************************************************************************/
422 static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
423 TALLOC_CTX *mem_ctx, int argc,
424 const char **argv)
426 WERROR result;
427 uint32 info_level = 1;
428 PORT_INFO_CTR ctr;
429 uint32 returned;
431 if (argc > 2) {
432 printf("Usage: %s [level]\n", argv[0]);
433 return WERR_OK;
436 if (argc == 2)
437 info_level = atoi(argv[1]);
439 /* Enumerate ports */
441 ZERO_STRUCT(ctr);
443 result = cli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
445 if (W_ERROR_IS_OK(result)) {
446 int i;
448 for (i = 0; i < returned; i++) {
449 switch (info_level) {
450 case 1:
451 display_port_info_1(&ctr.port.info_1[i]);
452 break;
453 case 2:
454 display_port_info_2(&ctr.port.info_2[i]);
455 break;
456 default:
457 printf("unknown info level %d\n", info_level);
458 break;
463 return result;
466 /****************************************************************************
467 ****************************************************************************/
469 static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
470 TALLOC_CTX *mem_ctx,
471 int argc, const char **argv)
473 POLICY_HND pol;
474 WERROR result;
475 uint32 info_level = 2;
476 BOOL opened_hnd = False;
477 PRINTER_INFO_CTR ctr;
478 fstring printername,
479 servername,
480 user,
481 comment;
483 if (argc == 1 || argc > 3) {
484 printf("Usage: %s printername comment\n", argv[0]);
486 return WERR_OK;
489 /* Open a printer handle */
490 if (argc == 3) {
491 fstrcpy(comment, argv[2]);
494 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
495 strupper_m(servername);
496 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
497 fstrcpy(user, cli->user_name);
499 /* get a printer handle */
500 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
501 PRINTER_ALL_ACCESS, servername,
502 user, &pol);
504 if (!W_ERROR_IS_OK(result))
505 goto done;
507 opened_hnd = True;
509 /* Get printer info */
510 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
512 if (!W_ERROR_IS_OK(result))
513 goto done;
516 /* Modify the comment. */
517 init_unistr(&ctr.printers_2->comment, comment);
518 ctr.printers_2->devmode = NULL;
519 ctr.printers_2->secdesc = NULL;
521 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
522 if (W_ERROR_IS_OK(result))
523 printf("Success in setting comment.\n");
525 done:
526 if (opened_hnd)
527 cli_spoolss_close_printer(cli, mem_ctx, &pol);
529 return result;
532 /****************************************************************************
533 ****************************************************************************/
535 static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
536 TALLOC_CTX *mem_ctx,
537 int argc, const char **argv)
539 POLICY_HND pol;
540 WERROR result;
541 uint32 info_level = 2;
542 BOOL opened_hnd = False;
543 PRINTER_INFO_CTR ctr;
544 fstring printername,
545 servername,
546 user,
547 new_printername;
549 if (argc == 1 || argc > 3) {
550 printf("Usage: %s printername new_printername\n", argv[0]);
552 return WERR_OK;
555 /* Open a printer handle */
556 if (argc == 3) {
557 fstrcpy(new_printername, argv[2]);
560 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
561 strupper_m(servername);
562 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
563 fstrcpy(user, cli->user_name);
565 /* get a printer handle */
566 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
567 PRINTER_ALL_ACCESS, servername,
568 user, &pol);
570 if (!W_ERROR_IS_OK(result))
571 goto done;
573 opened_hnd = True;
575 /* Get printer info */
576 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
578 if (!W_ERROR_IS_OK(result))
579 goto done;
581 /* Modify the printername. */
582 init_unistr(&ctr.printers_2->printername, new_printername);
583 ctr.printers_2->devmode = NULL;
584 ctr.printers_2->secdesc = NULL;
586 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
587 if (W_ERROR_IS_OK(result))
588 printf("Success in setting printername.\n");
590 done:
591 if (opened_hnd)
592 cli_spoolss_close_printer(cli, mem_ctx, &pol);
594 return result;
597 /****************************************************************************
598 ****************************************************************************/
600 static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
601 TALLOC_CTX *mem_ctx,
602 int argc, const char **argv)
604 POLICY_HND pol;
605 WERROR result;
606 uint32 info_level = 1;
607 BOOL opened_hnd = False;
608 PRINTER_INFO_CTR ctr;
609 fstring printername,
610 servername,
611 user;
613 if (argc == 1 || argc > 3) {
614 printf("Usage: %s <printername> [level]\n", argv[0]);
615 return WERR_OK;
618 /* Open a printer handle */
619 if (argc == 3) {
620 info_level = atoi(argv[2]);
623 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
624 strupper_m(servername);
625 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
626 fstrcpy(user, cli->user_name);
628 /* get a printer handle */
630 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
631 "", MAXIMUM_ALLOWED_ACCESS,
632 servername, user, &pol);
634 if (!W_ERROR_IS_OK(result))
635 goto done;
637 opened_hnd = True;
639 /* Get printer info */
641 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
643 if (!W_ERROR_IS_OK(result))
644 goto done;
646 /* Display printer info */
648 switch (info_level) {
649 case 0:
650 display_print_info_0(ctr.printers_0);
651 break;
652 case 1:
653 display_print_info_1(ctr.printers_1);
654 break;
655 case 2:
656 display_print_info_2(ctr.printers_2);
657 break;
658 case 3:
659 display_print_info_3(ctr.printers_3);
660 break;
661 case 7:
662 display_print_info_7(ctr.printers_7);
663 break;
664 default:
665 printf("unknown info level %d\n", info_level);
666 break;
669 done:
670 if (opened_hnd)
671 cli_spoolss_close_printer(cli, mem_ctx, &pol);
673 return result;
676 /****************************************************************************
677 ****************************************************************************/
679 static void display_reg_value(REGISTRY_VALUE value)
681 pstring text;
683 switch(value.type) {
684 case REG_DWORD:
685 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
686 *((uint32 *) value.data_p));
687 break;
688 case REG_SZ:
689 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
690 STR_TERMINATE);
691 printf("%s: REG_SZ: %s\n", value.valuename, text);
692 break;
693 case REG_BINARY:
694 printf("%s: REG_BINARY: unknown length value not displayed\n",
695 value.valuename);
696 break;
697 case REG_MULTI_SZ: {
698 uint16 *curstr = (uint16 *) value.data_p;
699 uint8 *start = value.data_p;
700 printf("%s: REG_MULTI_SZ:\n", value.valuename);
701 while ((*curstr != 0) &&
702 ((uint8 *) curstr < start + value.size)) {
703 rpcstr_pull(text, curstr, sizeof(text), -1,
704 STR_TERMINATE);
705 printf(" %s\n", text);
706 curstr += strlen(text) + 1;
709 break;
710 default:
711 printf("%s: unknown type %d\n", value.valuename, value.type);
716 /****************************************************************************
717 ****************************************************************************/
719 static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
720 TALLOC_CTX *mem_ctx,
721 int argc, const char **argv)
723 POLICY_HND pol;
724 WERROR result;
725 BOOL opened_hnd = False;
726 fstring printername,
727 servername,
728 user;
729 const char *valuename;
730 REGISTRY_VALUE value;
732 if (argc != 3) {
733 printf("Usage: %s <printername> <valuename>\n", argv[0]);
734 printf("<printername> of . queries print server\n");
735 return WERR_OK;
737 valuename = argv[2];
739 /* Open a printer handle */
741 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
742 strupper_m(servername);
743 if (strncmp(argv[1], ".", sizeof(".")) == 0)
744 fstrcpy(printername, servername);
745 else
746 slprintf(printername, sizeof(servername)-1, "%s\\%s",
747 servername, argv[1]);
748 fstrcpy(user, cli->user_name);
750 /* get a printer handle */
752 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
753 "", MAXIMUM_ALLOWED_ACCESS,
754 servername, user, &pol);
756 if (!W_ERROR_IS_OK(result))
757 goto done;
759 opened_hnd = True;
761 /* Get printer info */
763 result = cli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
765 if (!W_ERROR_IS_OK(result))
766 goto done;
768 /* Display printer data */
770 fstrcpy(value.valuename, valuename);
771 display_reg_value(value);
774 done:
775 if (opened_hnd)
776 cli_spoolss_close_printer(cli, mem_ctx, &pol);
778 return result;
781 /****************************************************************************
782 ****************************************************************************/
784 static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
785 TALLOC_CTX *mem_ctx,
786 int argc, const char **argv)
788 POLICY_HND pol;
789 WERROR result;
790 BOOL opened_hnd = False;
791 fstring printername,
792 servername,
793 user;
794 const char *valuename, *keyname;
795 REGISTRY_VALUE value;
797 if (argc != 4) {
798 printf("Usage: %s <printername> <keyname> <valuename>\n",
799 argv[0]);
800 printf("<printername> of . queries print server\n");
801 return WERR_OK;
803 valuename = argv[3];
804 keyname = argv[2];
806 /* Open a printer handle */
808 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
809 strupper_m(servername);
810 if (strncmp(argv[1], ".", sizeof(".")) == 0)
811 fstrcpy(printername, servername);
812 else
813 slprintf(printername, sizeof(printername)-1, "%s\\%s",
814 servername, argv[1]);
815 fstrcpy(user, cli->user_name);
817 /* get a printer handle */
819 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
820 "", MAXIMUM_ALLOWED_ACCESS,
821 servername, user, &pol);
823 if (!W_ERROR_IS_OK(result))
824 goto done;
826 opened_hnd = True;
828 /* Get printer info */
830 result = cli_spoolss_getprinterdataex(cli, mem_ctx, &pol, keyname,
831 valuename, &value);
833 if (!W_ERROR_IS_OK(result))
834 goto done;
836 /* Display printer data */
838 fstrcpy(value.valuename, valuename);
839 display_reg_value(value);
842 done:
843 if (opened_hnd)
844 cli_spoolss_close_printer(cli, mem_ctx, &pol);
846 return result;
849 /****************************************************************************
850 ****************************************************************************/
852 static void display_print_driver_1(DRIVER_INFO_1 *i1)
854 fstring name;
855 if (i1 == NULL)
856 return;
858 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
860 printf ("Printer Driver Info 1:\n");
861 printf ("\tDriver Name: [%s]\n\n", name);
863 return;
866 /****************************************************************************
867 ****************************************************************************/
869 static void display_print_driver_2(DRIVER_INFO_2 *i1)
871 fstring name;
872 fstring architecture;
873 fstring driverpath;
874 fstring datafile;
875 fstring configfile;
876 if (i1 == NULL)
877 return;
879 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
880 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
881 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
882 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
883 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
885 printf ("Printer Driver Info 2:\n");
886 printf ("\tVersion: [%x]\n", i1->version);
887 printf ("\tDriver Name: [%s]\n", name);
888 printf ("\tArchitecture: [%s]\n", architecture);
889 printf ("\tDriver Path: [%s]\n", driverpath);
890 printf ("\tDatafile: [%s]\n", datafile);
891 printf ("\tConfigfile: [%s]\n\n", configfile);
893 return;
896 /****************************************************************************
897 ****************************************************************************/
899 static void display_print_driver_3(DRIVER_INFO_3 *i1)
901 fstring name = "";
902 fstring architecture = "";
903 fstring driverpath = "";
904 fstring datafile = "";
905 fstring configfile = "";
906 fstring helpfile = "";
907 fstring dependentfiles = "";
908 fstring monitorname = "";
909 fstring defaultdatatype = "";
911 int length=0;
912 BOOL valid = True;
914 if (i1 == NULL)
915 return;
917 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
918 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
919 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
920 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
921 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
922 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
923 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
924 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
926 printf ("Printer Driver Info 3:\n");
927 printf ("\tVersion: [%x]\n", i1->version);
928 printf ("\tDriver Name: [%s]\n",name);
929 printf ("\tArchitecture: [%s]\n", architecture);
930 printf ("\tDriver Path: [%s]\n", driverpath);
931 printf ("\tDatafile: [%s]\n", datafile);
932 printf ("\tConfigfile: [%s]\n", configfile);
933 printf ("\tHelpfile: [%s]\n\n", helpfile);
935 while (valid)
937 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
939 length+=strlen(dependentfiles)+1;
941 if (strlen(dependentfiles) > 0)
943 printf ("\tDependentfiles: [%s]\n", dependentfiles);
945 else
947 valid = False;
951 printf ("\n");
953 printf ("\tMonitorname: [%s]\n", monitorname);
954 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
956 return;
959 /****************************************************************************
960 ****************************************************************************/
962 static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
963 TALLOC_CTX *mem_ctx,
964 int argc, const char **argv)
966 POLICY_HND pol;
967 WERROR werror;
968 uint32 info_level = 3;
969 BOOL opened_hnd = False;
970 PRINTER_DRIVER_CTR ctr;
971 fstring printername,
972 servername,
973 user;
974 uint32 i;
975 BOOL success = False;
977 if ((argc == 1) || (argc > 3))
979 printf("Usage: %s <printername> [level]\n", argv[0]);
980 return WERR_OK;
983 /* get the arguments need to open the printer handle */
984 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
985 strupper_m(servername);
986 fstrcpy(user, cli->user_name);
987 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
988 if (argc == 3)
989 info_level = atoi(argv[2]);
991 /* Open a printer handle */
993 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
994 PRINTER_ACCESS_USE,
995 servername, user, &pol);
997 if (!W_ERROR_IS_OK(werror)) {
998 printf("Error opening printer handle for %s!\n", printername);
999 return werror;
1002 opened_hnd = True;
1004 /* loop through and print driver info level for each architecture */
1006 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1008 werror = cli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
1009 archi_table[i].long_archi, archi_table[i].version,
1010 &ctr);
1012 if (!W_ERROR_IS_OK(werror))
1013 continue;
1015 /* need at least one success */
1017 success = True;
1019 printf ("\n[%s]\n", archi_table[i].long_archi);
1021 switch (info_level) {
1022 case 1:
1023 display_print_driver_1 (ctr.info1);
1024 break;
1025 case 2:
1026 display_print_driver_2 (ctr.info2);
1027 break;
1028 case 3:
1029 display_print_driver_3 (ctr.info3);
1030 break;
1031 default:
1032 printf("unknown info level %d\n", info_level);
1033 break;
1037 /* Cleanup */
1039 if (opened_hnd)
1040 cli_spoolss_close_printer (cli, mem_ctx, &pol);
1042 if ( success )
1043 werror = WERR_OK;
1045 return werror;
1048 /****************************************************************************
1049 ****************************************************************************/
1051 static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
1052 TALLOC_CTX *mem_ctx,
1053 int argc, const char **argv)
1055 WERROR werror;
1056 uint32 info_level = 1;
1057 PRINTER_DRIVER_CTR ctr;
1058 uint32 i, j,
1059 returned;
1061 if (argc > 2)
1063 printf("Usage: enumdrivers [level]\n");
1064 return WERR_OK;
1067 if (argc == 2)
1068 info_level = atoi(argv[1]);
1071 /* loop through and print driver info level for each architecture */
1072 for (i=0; archi_table[i].long_archi!=NULL; i++)
1074 /* check to see if we already asked for this architecture string */
1076 if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
1077 continue;
1079 werror = cli_spoolss_enumprinterdrivers(
1080 cli, mem_ctx, info_level,
1081 archi_table[i].long_archi, &returned, &ctr);
1083 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1084 printf ("Server does not support environment [%s]\n",
1085 archi_table[i].long_archi);
1086 werror = WERR_OK;
1087 continue;
1090 if (returned == 0)
1091 continue;
1093 if (!W_ERROR_IS_OK(werror)) {
1094 printf ("Error getting driver for environment [%s] - %d\n",
1095 archi_table[i].long_archi, W_ERROR_V(werror));
1096 continue;
1099 printf ("\n[%s]\n", archi_table[i].long_archi);
1100 switch (info_level)
1103 case 1:
1104 for (j=0; j < returned; j++) {
1105 display_print_driver_1 (&(ctr.info1[j]));
1107 break;
1108 case 2:
1109 for (j=0; j < returned; j++) {
1110 display_print_driver_2 (&(ctr.info2[j]));
1112 break;
1113 case 3:
1114 for (j=0; j < returned; j++) {
1115 display_print_driver_3 (&(ctr.info3[j]));
1117 break;
1118 default:
1119 printf("unknown info level %d\n", info_level);
1120 break;
1124 return werror;
1127 /****************************************************************************
1128 ****************************************************************************/
1130 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1132 fstring name;
1133 if (i1 == NULL)
1134 return;
1136 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1138 printf ("\tDirectory Name:[%s]\n", name);
1141 /****************************************************************************
1142 ****************************************************************************/
1144 static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
1145 TALLOC_CTX *mem_ctx,
1146 int argc, const char **argv)
1148 WERROR result;
1149 fstring env;
1150 DRIVER_DIRECTORY_CTR ctr;
1152 if (argc > 2) {
1153 printf("Usage: %s [environment]\n", argv[0]);
1154 return WERR_OK;
1157 /* Get the arguments need to open the printer handle */
1159 if (argc == 2)
1160 fstrcpy (env, argv[1]);
1161 else
1162 fstrcpy (env, "Windows NT x86");
1164 /* Get the directory. Only use Info level 1 */
1166 result = cli_spoolss_getprinterdriverdir(cli, mem_ctx, 1, env, &ctr);
1168 if (W_ERROR_IS_OK(result))
1169 display_printdriverdir_1(ctr.info1);
1171 return result;
1174 /****************************************************************************
1175 ****************************************************************************/
1177 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1180 int i;
1182 for (i=0; archi_table[i].long_archi != NULL; i++)
1184 if (strcmp(arch, archi_table[i].short_archi) == 0)
1186 info->version = archi_table[i].version;
1187 init_unistr (&info->architecture, archi_table[i].long_archi);
1188 break;
1192 if (archi_table[i].long_archi == NULL)
1194 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1197 return;
1201 /**************************************************************************
1202 wrapper for strtok to get the next parameter from a delimited list.
1203 Needed to handle the empty parameter string denoted by "NULL"
1204 *************************************************************************/
1206 static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
1208 char *ptr;
1210 /* get the next token */
1211 ptr = strtok(str, delim);
1213 /* a string of 'NULL' is used to represent an empty
1214 parameter because two consecutive delimiters
1215 will not return an empty string. See man strtok(3)
1216 for details */
1217 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
1218 ptr = NULL;
1220 if (dest != NULL)
1221 init_unistr(dest, ptr);
1223 return ptr;
1226 /********************************************************************************
1227 fill in the members of a DRIVER_INFO_3 struct using a character
1228 string in the form of
1229 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1230 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1231 <Default Data Type>:<Comma Separated list of Files>
1232 *******************************************************************************/
1233 static BOOL init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
1234 char *args )
1236 char *str, *str2;
1237 uint32 len, i;
1239 /* fill in the UNISTR fields */
1240 str = get_driver_3_param (args, ":", &info->name);
1241 str = get_driver_3_param (NULL, ":", &info->driverpath);
1242 str = get_driver_3_param (NULL, ":", &info->datafile);
1243 str = get_driver_3_param (NULL, ":", &info->configfile);
1244 str = get_driver_3_param (NULL, ":", &info->helpfile);
1245 str = get_driver_3_param (NULL, ":", &info->monitorname);
1246 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1248 /* <Comma Separated List of Dependent Files> */
1249 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1250 str = str2;
1252 /* begin to strip out each filename */
1253 str = strtok(str, ",");
1254 len = 0;
1255 while (str != NULL)
1257 /* keep a cumlative count of the str lengths */
1258 len += strlen(str)+1;
1259 str = strtok(NULL, ",");
1262 /* allocate the space; add one extra slot for a terminating NULL.
1263 Each filename is NULL terminated and the end contains a double
1264 NULL */
1265 if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL)
1267 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1268 return False;
1270 for (i=0; i<len; i++)
1272 SSVAL(&info->dependentfiles[i], 0, str2[i]);
1274 info->dependentfiles[len] = '\0';
1276 return True;
1280 /****************************************************************************
1281 ****************************************************************************/
1283 static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
1284 TALLOC_CTX *mem_ctx,
1285 int argc, const char **argv)
1287 WERROR result;
1288 uint32 level = 3;
1289 PRINTER_DRIVER_CTR ctr;
1290 DRIVER_INFO_3 info3;
1291 const char *arch;
1292 fstring driver_name;
1293 char *driver_args;
1295 /* parse the command arguements */
1296 if (argc != 3 && argc != 4)
1298 printf ("Usage: %s <Environment> \\\n", argv[0]);
1299 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1300 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1301 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1302 printf ("\t[version]\n");
1304 return WERR_OK;
1307 /* Fill in the DRIVER_INFO_3 struct */
1308 ZERO_STRUCT(info3);
1309 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
1311 printf ("Error Unknown architechture [%s]\n", argv[1]);
1312 return WERR_INVALID_PARAM;
1314 else
1315 set_drv_info_3_env(&info3, arch);
1317 driver_args = talloc_strdup( mem_ctx, argv[2] );
1318 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1320 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1321 return WERR_INVALID_PARAM;
1324 /* if printer driver version specified, override the default version
1325 * used by the architecture. This allows installation of Windows
1326 * 2000 (version 3) printer drivers. */
1327 if (argc == 4)
1329 info3.version = atoi(argv[3]);
1333 ctr.info3 = &info3;
1334 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1336 if (W_ERROR_IS_OK(result)) {
1337 rpcstr_pull(driver_name, info3.name.buffer,
1338 sizeof(driver_name), -1, STR_TERMINATE);
1339 printf ("Printer Driver %s successfully installed.\n",
1340 driver_name);
1343 return result;
1347 /****************************************************************************
1348 ****************************************************************************/
1350 static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
1351 TALLOC_CTX *mem_ctx,
1352 int argc, const char **argv)
1354 WERROR result;
1355 uint32 level = 2;
1356 PRINTER_INFO_CTR ctr;
1357 PRINTER_INFO_2 info2;
1358 fstring servername;
1360 /* parse the command arguements */
1361 if (argc != 5)
1363 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1364 return WERR_OK;
1367 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1368 strupper_m(servername);
1370 /* Fill in the DRIVER_INFO_2 struct */
1371 ZERO_STRUCT(info2);
1373 init_unistr( &info2.printername, argv[1]);
1374 init_unistr( &info2.sharename, argv[2]);
1375 init_unistr( &info2.drivername, argv[3]);
1376 init_unistr( &info2.portname, argv[4]);
1377 init_unistr( &info2.comment, "Created by rpcclient");
1378 init_unistr( &info2.printprocessor, "winprint");
1379 init_unistr( &info2.datatype, "RAW");
1380 info2.devmode = NULL;
1381 info2.secdesc = NULL;
1382 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1383 info2.priority = 0;
1384 info2.defaultpriority = 0;
1385 info2.starttime = 0;
1386 info2.untiltime = 0;
1388 /* These three fields must not be used by AddPrinter()
1389 as defined in the MS Platform SDK documentation..
1390 --jerry
1391 info2.status = 0;
1392 info2.cjobs = 0;
1393 info2.averageppm = 0;
1396 ctr.printers_2 = &info2;
1397 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1399 if (W_ERROR_IS_OK(result))
1400 printf ("Printer %s successfully installed.\n", argv[1]);
1402 return result;
1405 /****************************************************************************
1406 ****************************************************************************/
1408 static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
1409 TALLOC_CTX *mem_ctx,
1410 int argc, const char **argv)
1412 POLICY_HND pol;
1413 WERROR result;
1414 uint32 level = 2;
1415 BOOL opened_hnd = False;
1416 PRINTER_INFO_CTR ctr;
1417 PRINTER_INFO_2 info2;
1418 fstring servername,
1419 printername,
1420 user;
1422 /* parse the command arguements */
1423 if (argc != 3)
1425 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1426 return WERR_OK;
1429 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1430 strupper_m(servername);
1431 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1432 fstrcpy(user, cli->user_name);
1434 /* Get a printer handle */
1436 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1437 PRINTER_ALL_ACCESS,
1438 servername, user, &pol);
1440 if (!W_ERROR_IS_OK(result))
1441 goto done;
1443 opened_hnd = True;
1445 /* Get printer info */
1447 ZERO_STRUCT (info2);
1448 ctr.printers_2 = &info2;
1450 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
1452 if (!W_ERROR_IS_OK(result)) {
1453 printf ("Unable to retrieve printer information!\n");
1454 goto done;
1457 /* Set the printer driver */
1459 init_unistr(&ctr.printers_2->drivername, argv[2]);
1461 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1463 if (!W_ERROR_IS_OK(result)) {
1464 printf("SetPrinter call failed!\n");
1465 goto done;;
1468 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1470 done:
1471 /* Cleanup */
1473 if (opened_hnd)
1474 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1476 return result;
1480 /****************************************************************************
1481 ****************************************************************************/
1483 static WERROR cmd_spoolss_deletedriverex(struct cli_state *cli,
1484 TALLOC_CTX *mem_ctx,
1485 int argc, const char **argv)
1487 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1489 int i;
1490 int vers = -1;
1492 const char *arch = NULL;
1494 /* parse the command arguements */
1495 if (argc < 2 || argc > 4) {
1496 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1497 return WERR_OK;
1500 if (argc >= 3)
1501 arch = argv[2];
1502 if (argc == 4)
1503 vers = atoi (argv[3]);
1506 /* delete the driver for all architectures */
1507 for (i=0; archi_table[i].long_archi; i++) {
1509 if (arch && !strequal( archi_table[i].long_archi, arch))
1510 continue;
1512 if (vers >= 0 && archi_table[i].version != vers)
1513 continue;
1515 /* make the call to remove the driver */
1516 result = cli_spoolss_deleteprinterdriverex(
1517 cli, mem_ctx, archi_table[i].long_archi, argv[1], archi_table[i].version);
1519 if ( !W_ERROR_IS_OK(result) )
1521 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1522 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1523 argv[1], archi_table[i].long_archi, archi_table[i].version, dos_errstr(result));
1526 else
1528 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1529 archi_table[i].long_archi, archi_table[i].version);
1530 ret = WERR_OK;
1534 return ret;
1538 /****************************************************************************
1539 ****************************************************************************/
1541 static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
1542 TALLOC_CTX *mem_ctx,
1543 int argc, const char **argv)
1545 WERROR result;
1546 fstring servername;
1547 int i;
1549 /* parse the command arguements */
1550 if (argc != 2)
1552 printf ("Usage: %s <driver>\n", argv[0]);
1553 return WERR_OK;
1556 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1557 strupper_m(servername);
1559 /* delete the driver for all architectures */
1560 for (i=0; archi_table[i].long_archi; i++)
1562 /* make the call to remove the driver */
1563 result = cli_spoolss_deleteprinterdriver(
1564 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1566 if ( !W_ERROR_IS_OK(result) ) {
1567 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1568 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1569 argv[1], archi_table[i].long_archi,
1570 W_ERROR_V(result));
1573 else
1575 printf ("Driver %s removed for arch [%s].\n", argv[1],
1576 archi_table[i].long_archi);
1580 return result;
1583 /****************************************************************************
1584 ****************************************************************************/
1586 static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
1587 TALLOC_CTX *mem_ctx,
1588 int argc, const char **argv)
1590 WERROR result;
1591 char *servername = NULL, *environment = NULL;
1592 fstring procdir;
1594 /* parse the command arguements */
1595 if (argc > 2) {
1596 printf ("Usage: %s [environment]\n", argv[0]);
1597 return WERR_OK;
1600 if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
1601 return WERR_NOMEM;
1602 strupper_m(servername);
1604 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1605 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1606 SAFE_FREE(servername);
1607 return WERR_NOMEM;
1610 result = cli_spoolss_getprintprocessordirectory(
1611 cli, mem_ctx, servername, environment, procdir);
1613 if (W_ERROR_IS_OK(result))
1614 printf("%s\n", procdir);
1616 SAFE_FREE(servername);
1617 SAFE_FREE(environment);
1619 return result;
1622 /****************************************************************************
1623 ****************************************************************************/
1625 static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1626 int argc, const char **argv)
1628 POLICY_HND handle;
1629 WERROR werror;
1630 char *servername = NULL, *printername = NULL;
1631 FORM form;
1632 BOOL got_handle = False;
1634 /* Parse the command arguements */
1636 if (argc != 3) {
1637 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1638 return WERR_OK;
1641 /* Get a printer handle */
1643 asprintf(&servername, "\\\\%s", cli->desthost);
1644 strupper_m(servername);
1645 asprintf(&printername, "%s\\%s", servername, argv[1]);
1647 werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1648 PRINTER_ALL_ACCESS,
1649 servername, cli->user_name, &handle);
1651 if (!W_ERROR_IS_OK(werror))
1652 goto done;
1654 got_handle = True;
1656 /* Dummy up some values for the form data */
1658 form.flags = FORM_USER;
1659 form.size_x = form.size_y = 100;
1660 form.left = 0;
1661 form.top = 10;
1662 form.right = 20;
1663 form.bottom = 30;
1665 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1667 /* Add the form */
1670 werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1672 done:
1673 if (got_handle)
1674 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1676 SAFE_FREE(servername);
1677 SAFE_FREE(printername);
1679 return werror;
1682 /****************************************************************************
1683 ****************************************************************************/
1685 static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1686 int argc, const char **argv)
1688 POLICY_HND handle;
1689 WERROR werror;
1690 char *servername = NULL, *printername = NULL;
1691 FORM form;
1692 BOOL got_handle = False;
1694 /* Parse the command arguements */
1696 if (argc != 3) {
1697 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1698 return WERR_OK;
1701 /* Get a printer handle */
1703 asprintf(&servername, "\\\\%s", cli->desthost);
1704 strupper_m(servername);
1705 asprintf(&printername, "%s\\%s", servername, argv[1]);
1707 werror = cli_spoolss_open_printer_ex(
1708 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1709 servername, cli->user_name, &handle);
1711 if (!W_ERROR_IS_OK(werror))
1712 goto done;
1714 got_handle = True;
1716 /* Dummy up some values for the form data */
1718 form.flags = FORM_PRINTER;
1719 form.size_x = form.size_y = 100;
1720 form.left = 0;
1721 form.top = 1000;
1722 form.right = 2000;
1723 form.bottom = 3000;
1725 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1727 /* Set the form */
1729 werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1731 done:
1732 if (got_handle)
1733 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1735 SAFE_FREE(servername);
1736 SAFE_FREE(printername);
1738 return werror;
1741 /****************************************************************************
1742 ****************************************************************************/
1744 static const char *get_form_flag(int form_flag)
1746 switch (form_flag) {
1747 case FORM_USER:
1748 return "FORM_USER";
1749 case FORM_BUILTIN:
1750 return "FORM_BUILTIN";
1751 case FORM_PRINTER:
1752 return "FORM_PRINTER";
1753 default:
1754 return "unknown";
1758 /****************************************************************************
1759 ****************************************************************************/
1761 static void display_form(FORM_1 *form)
1763 fstring form_name = "";
1765 if (form->name.buffer)
1766 rpcstr_pull(form_name, form->name.buffer,
1767 sizeof(form_name), -1, STR_TERMINATE);
1769 printf("%s\n" \
1770 "\tflag: %s (%d)\n" \
1771 "\twidth: %d, length: %d\n" \
1772 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1773 form_name, get_form_flag(form->flag), form->flag,
1774 form->width, form->length,
1775 form->left, form->right,
1776 form->top, form->bottom);
1779 /****************************************************************************
1780 ****************************************************************************/
1782 static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1783 int argc, const char **argv)
1785 POLICY_HND handle;
1786 WERROR werror;
1787 char *servername = NULL, *printername = NULL;
1788 FORM_1 form;
1789 BOOL got_handle = False;
1791 /* Parse the command arguements */
1793 if (argc != 3) {
1794 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1795 return WERR_OK;
1798 /* Get a printer handle */
1800 asprintf(&servername, "\\\\%s", cli->desthost);
1801 strupper_m(servername);
1802 asprintf(&printername, "%s\\%s", servername, argv[1]);
1804 werror = cli_spoolss_open_printer_ex(
1805 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1806 servername, cli->user_name, &handle);
1808 if (!W_ERROR_IS_OK(werror))
1809 goto done;
1811 got_handle = True;
1813 /* Get the form */
1815 werror = cli_spoolss_getform(cli, mem_ctx, &handle, argv[2], 1, &form);
1817 if (!W_ERROR_IS_OK(werror))
1818 goto done;
1820 display_form(&form);
1822 done:
1823 if (got_handle)
1824 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1826 SAFE_FREE(servername);
1827 SAFE_FREE(printername);
1829 return werror;
1832 /****************************************************************************
1833 ****************************************************************************/
1835 static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
1836 TALLOC_CTX *mem_ctx, int argc,
1837 const char **argv)
1839 POLICY_HND handle;
1840 WERROR werror;
1841 char *servername = NULL, *printername = NULL;
1842 BOOL got_handle = False;
1844 /* Parse the command arguements */
1846 if (argc != 3) {
1847 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1848 return WERR_OK;
1851 /* Get a printer handle */
1853 asprintf(&servername, "\\\\%s", cli->desthost);
1854 strupper_m(servername);
1855 asprintf(&printername, "%s\\%s", servername, argv[1]);
1857 werror = cli_spoolss_open_printer_ex(
1858 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1859 servername, cli->user_name, &handle);
1861 if (!W_ERROR_IS_OK(werror))
1862 goto done;
1864 got_handle = True;
1866 /* Delete the form */
1868 werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1870 done:
1871 if (got_handle)
1872 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1874 SAFE_FREE(servername);
1875 SAFE_FREE(printername);
1877 return werror;
1880 /****************************************************************************
1881 ****************************************************************************/
1883 static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
1884 TALLOC_CTX *mem_ctx, int argc,
1885 const char **argv)
1887 POLICY_HND handle;
1888 WERROR werror;
1889 char *servername = NULL, *printername = NULL;
1890 BOOL got_handle = False;
1891 uint32 needed, offered, num_forms, level = 1, i;
1892 FORM_1 *forms;
1894 /* Parse the command arguements */
1896 if (argc != 2) {
1897 printf ("Usage: %s <printer>\n", argv[0]);
1898 return WERR_OK;
1901 /* Get a printer handle */
1903 asprintf(&servername, "\\\\%s", cli->desthost);
1904 strupper_m(servername);
1905 asprintf(&printername, "%s\\%s", servername, argv[1]);
1907 werror = cli_spoolss_open_printer_ex(
1908 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1909 servername, cli->user_name, &handle);
1911 if (!W_ERROR_IS_OK(werror))
1912 goto done;
1914 got_handle = True;
1916 /* Enumerate forms */
1918 offered = needed = 0;
1919 werror = cli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
1921 if (!W_ERROR_IS_OK(werror))
1922 goto done;
1924 /* Display output */
1926 for (i = 0; i < num_forms; i++) {
1928 display_form(&forms[i]);
1932 done:
1933 if (got_handle)
1934 cli_spoolss_close_printer(cli, mem_ctx, &handle);
1936 SAFE_FREE(servername);
1937 SAFE_FREE(printername);
1939 return werror;
1942 /****************************************************************************
1943 ****************************************************************************/
1945 static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
1946 TALLOC_CTX *mem_ctx,
1947 int argc, const char **argv)
1949 WERROR result;
1950 fstring servername, printername, user;
1951 POLICY_HND pol;
1952 BOOL opened_hnd = False;
1953 PRINTER_INFO_CTR ctr;
1954 PRINTER_INFO_0 info;
1955 REGISTRY_VALUE value;
1956 UNISTR2 data;
1958 /* parse the command arguements */
1959 if (argc != 4) {
1960 printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
1961 return WERR_OK;
1964 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
1965 strupper_m(servername);
1966 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1967 fstrcpy(user, cli->user_name);
1969 /* get a printer handle */
1970 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1971 MAXIMUM_ALLOWED_ACCESS, servername,
1972 user, &pol);
1973 if (!W_ERROR_IS_OK(result))
1974 goto done;
1976 opened_hnd = True;
1978 ctr.printers_0 = &info;
1980 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
1982 if (!W_ERROR_IS_OK(result))
1983 goto done;
1985 printf("%s\n", timestring(True));
1986 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
1988 /* Set the printer data */
1990 init_unistr2(&data, argv[3], UNI_STR_TERMINATE);
1991 fstrcpy(value.valuename, argv[2]);
1992 value.type = REG_SZ;
1993 value.size = data.uni_str_len * 2;
1994 value.data_p = TALLOC_MEMDUP(mem_ctx, data.buffer, value.size);
1996 result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
1998 if (!W_ERROR_IS_OK(result)) {
1999 printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
2000 goto done;
2002 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
2004 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
2006 if (!W_ERROR_IS_OK(result))
2007 goto done;
2009 printf("%s\n", timestring(True));
2010 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
2012 done:
2013 /* cleanup */
2014 if (opened_hnd)
2015 cli_spoolss_close_printer(cli, mem_ctx, &pol);
2017 return result;
2020 /****************************************************************************
2021 ****************************************************************************/
2023 static void display_job_info_1(JOB_INFO_1 *job)
2025 fstring username = "", document = "", text_status = "";
2027 rpcstr_pull(username, job->username.buffer,
2028 sizeof(username), -1, STR_TERMINATE);
2030 rpcstr_pull(document, job->document.buffer,
2031 sizeof(document), -1, STR_TERMINATE);
2033 rpcstr_pull(text_status, job->text_status.buffer,
2034 sizeof(text_status), -1, STR_TERMINATE);
2036 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
2037 username, document, text_status, job->pagesprinted,
2038 job->totalpages);
2041 /****************************************************************************
2042 ****************************************************************************/
2044 static void display_job_info_2(JOB_INFO_2 *job)
2046 fstring username = "", document = "", text_status = "";
2048 rpcstr_pull(username, job->username.buffer,
2049 sizeof(username), -1, STR_TERMINATE);
2051 rpcstr_pull(document, job->document.buffer,
2052 sizeof(document), -1, STR_TERMINATE);
2054 rpcstr_pull(text_status, job->text_status.buffer,
2055 sizeof(text_status), -1, STR_TERMINATE);
2057 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
2058 username, document, text_status, job->pagesprinted,
2059 job->totalpages, job->size);
2062 /****************************************************************************
2063 ****************************************************************************/
2065 static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
2066 TALLOC_CTX *mem_ctx, int argc,
2067 const char **argv)
2069 WERROR result;
2070 uint32 needed, offered, level = 1, num_jobs, i;
2071 BOOL got_hnd = False;
2072 pstring printername;
2073 fstring servername, user;
2074 POLICY_HND hnd;
2075 JOB_INFO_CTR ctr;
2077 if (argc < 2 || argc > 3) {
2078 printf("Usage: %s printername [level]\n", argv[0]);
2079 return WERR_OK;
2082 if (argc == 3)
2083 level = atoi(argv[2]);
2085 /* Open printer handle */
2087 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2088 strupper_m(servername);
2089 fstrcpy(user, cli->user_name);
2090 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
2091 strupper_m(printername);
2092 pstrcat(printername, argv[1]);
2094 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2095 "", MAXIMUM_ALLOWED_ACCESS,
2096 servername, user, &hnd);
2098 if (!W_ERROR_IS_OK(result))
2099 goto done;
2101 got_hnd = True;
2103 /* Enumerate ports */
2105 offered = needed = 0;
2106 result = cli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
2107 &num_jobs, &ctr);
2109 if (!W_ERROR_IS_OK(result))
2110 goto done;
2112 for (i = 0; i < num_jobs; i++) {
2113 switch(level) {
2114 case 1:
2115 display_job_info_1(&ctr.job.job_info_1[i]);
2116 break;
2117 case 2:
2118 display_job_info_2(&ctr.job.job_info_2[i]);
2119 break;
2120 default:
2121 d_printf("unknown info level %d\n", level);
2122 break;
2126 done:
2127 if (got_hnd)
2128 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2130 return result;
2133 /****************************************************************************
2134 ****************************************************************************/
2136 static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
2137 TALLOC_CTX *mem_ctx, int argc,
2138 const char **argv)
2140 WERROR result;
2141 uint32 i=0, val_needed, data_needed;
2142 BOOL got_hnd = False;
2143 pstring printername;
2144 fstring servername, user;
2145 POLICY_HND hnd;
2147 if (argc != 2) {
2148 printf("Usage: %s printername\n", argv[0]);
2149 return WERR_OK;
2152 /* Open printer handle */
2154 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2155 strupper_m(servername);
2156 fstrcpy(user, cli->user_name);
2157 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2158 strupper_m(printername);
2159 pstrcat(printername, argv[1]);
2161 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2162 "", MAXIMUM_ALLOWED_ACCESS,
2163 servername, user, &hnd);
2165 if (!W_ERROR_IS_OK(result))
2166 goto done;
2168 got_hnd = True;
2170 /* Enumerate data */
2172 result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2173 &val_needed, &data_needed,
2174 NULL);
2175 while (W_ERROR_IS_OK(result)) {
2176 REGISTRY_VALUE value;
2177 result = cli_spoolss_enumprinterdata(
2178 cli, mem_ctx, &hnd, i++, val_needed,
2179 data_needed, 0, 0, &value);
2180 if (W_ERROR_IS_OK(result))
2181 display_reg_value(value);
2183 if (W_ERROR_V(result) == ERRnomoreitems)
2184 result = W_ERROR(ERRsuccess);
2186 done:
2187 if (got_hnd)
2188 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2190 return result;
2193 /****************************************************************************
2194 ****************************************************************************/
2196 static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
2197 TALLOC_CTX *mem_ctx, int argc,
2198 const char **argv)
2200 WERROR result;
2201 uint32 i;
2202 BOOL got_hnd = False;
2203 pstring printername;
2204 fstring servername, user;
2205 const char *keyname = NULL;
2206 POLICY_HND hnd;
2207 REGVAL_CTR ctr;
2209 if (argc != 3) {
2210 printf("Usage: %s printername <keyname>\n", argv[0]);
2211 return WERR_OK;
2214 keyname = argv[2];
2216 /* Open printer handle */
2218 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2219 strupper_m(servername);
2220 fstrcpy(user, cli->user_name);
2221 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2222 strupper_m(printername);
2223 pstrcat(printername, argv[1]);
2225 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2226 "", MAXIMUM_ALLOWED_ACCESS,
2227 servername, user, &hnd);
2229 if (!W_ERROR_IS_OK(result))
2230 goto done;
2232 got_hnd = True;
2234 /* Enumerate subkeys */
2236 result = cli_spoolss_enumprinterdataex(
2237 cli, mem_ctx, &hnd, keyname, NULL);
2239 if (!W_ERROR_IS_OK(result))
2240 goto done;
2242 for (i=0; i < ctr.num_values; i++) {
2243 display_reg_value(*(ctr.values[i]));
2246 regval_ctr_destroy(&ctr);
2248 done:
2249 if (got_hnd)
2250 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2252 return result;
2255 /****************************************************************************
2256 ****************************************************************************/
2258 static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
2259 TALLOC_CTX *mem_ctx, int argc,
2260 const char **argv)
2262 WERROR result;
2263 BOOL got_hnd = False;
2264 pstring printername;
2265 fstring servername, user;
2266 const char *keyname = NULL;
2267 POLICY_HND hnd;
2268 uint16 *keylist = NULL, *curkey;
2270 if (argc < 2 || argc > 3) {
2271 printf("Usage: %s printername [keyname]\n", argv[0]);
2272 return WERR_OK;
2275 if (argc == 3)
2276 keyname = argv[2];
2277 else
2278 keyname = "";
2280 /* Open printer handle */
2282 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
2283 strupper_m(servername);
2284 fstrcpy(user, cli->user_name);
2285 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
2286 strupper_m(printername);
2287 pstrcat(printername, argv[1]);
2289 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2290 "", MAXIMUM_ALLOWED_ACCESS,
2291 servername, user, &hnd);
2293 if (!W_ERROR_IS_OK(result))
2294 goto done;
2296 got_hnd = True;
2298 /* Enumerate subkeys */
2300 result = cli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, NULL, NULL);
2302 if (!W_ERROR_IS_OK(result))
2303 goto done;
2305 curkey = keylist;
2306 while (*curkey != 0) {
2307 pstring subkey;
2308 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2309 STR_TERMINATE);
2310 printf("%s\n", subkey);
2311 curkey += strlen(subkey) + 1;
2314 safe_free(keylist);
2316 done:
2317 if (got_hnd)
2318 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2320 return result;
2323 /****************************************************************************
2324 ****************************************************************************/
2326 static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
2327 TALLOC_CTX *mem_ctx, int argc,
2328 const char **argv)
2330 fstring servername, printername;
2331 POLICY_HND hnd;
2332 BOOL got_hnd = False;
2333 WERROR result;
2334 SPOOL_NOTIFY_OPTION option;
2336 if (argc != 2) {
2337 printf("Usage: %s printername\n", argv[0]);
2338 result = WERR_OK;
2339 goto done;
2342 /* Open printer */
2344 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
2345 strupper_m(servername);
2347 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
2348 argv[1]);
2349 strupper_m(printername);
2351 result = cli_spoolss_open_printer_ex(
2352 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2353 servername, cli->user_name, &hnd);
2355 if (!W_ERROR_IS_OK(result)) {
2356 printf("Error opening %s\n", argv[1]);
2357 goto done;
2360 got_hnd = True;
2362 /* Create spool options */
2364 ZERO_STRUCT(option);
2366 option.version = 2;
2367 option.option_type_ptr = 1;
2368 option.count = option.ctr.count = 2;
2370 option.ctr.type = TALLOC_ARRAY(mem_ctx, SPOOL_NOTIFY_OPTION_TYPE, 2);
2372 ZERO_STRUCT(option.ctr.type[0]);
2373 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2374 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2375 option.ctr.type[0].fields_ptr = 1;
2376 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2378 ZERO_STRUCT(option.ctr.type[1]);
2379 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2380 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2381 option.ctr.type[1].fields_ptr = 1;
2382 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2384 /* Send rffpcnex */
2386 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2387 strupper_m(servername);
2389 result = cli_spoolss_rffpcnex(
2390 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2392 if (!W_ERROR_IS_OK(result)) {
2393 printf("Error rffpcnex %s\n", argv[1]);
2394 goto done;
2397 done:
2398 if (got_hnd)
2399 cli_spoolss_close_printer(cli, mem_ctx, &hnd);
2401 return result;
2404 /* List of commands exported by this module */
2405 struct cmd_set spoolss_commands[] = {
2407 { "SPOOLSS" },
2409 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
2410 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
2411 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
2412 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, PI_SPOOLSS, "Delete a printer driver with files", "" },
2413 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
2414 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
2415 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
2416 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
2417 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
2418 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
2419 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
2420 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
2421 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
2422 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
2423 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
2424 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
2425 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
2426 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
2427 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
2428 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
2429 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
2430 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
2431 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
2432 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
2433 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
2434 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, PI_SPOOLSS, "Set printername", "" },
2435 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
2436 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },
2438 { NULL }