2 Unix SMB/CIFS implementation.
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.
26 #include "rpcclient.h"
29 const char *long_archi
;
30 const char *short_archi
;
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 },
57 * rpcclient module for SPOOLSS rpc pipe.
59 * This generally just parses and checks command lines, and then calls
60 * a cli_spoolss function.
63 /****************************************************************************
64 function to do the mapping between the long architecture name and
66 ****************************************************************************/
68 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
72 DEBUG(107,("Getting architecture dependant directory\n"));
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
));
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
,
98 int argc
, const char **argv
)
102 fstring servername
, user
;
106 printf("Usage: %s <printername>\n", argv
[0]);
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
));
138 /****************************************************************************
139 ****************************************************************************/
141 static void display_print_info_0(PRINTER_INFO_0
*i0
)
144 fstring servername
= "";
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
);
196 /****************************************************************************
197 ****************************************************************************/
199 static void display_print_info_1(PRINTER_INFO_1
*i1
)
205 rpcstr_pull(desc
, i1
->description
.buffer
, sizeof(desc
), -1,
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
);
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
);
269 display_sec_desc(i2
->secdesc
);
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
);
286 /****************************************************************************
287 ****************************************************************************/
289 static void display_print_info_7(PRINTER_INFO_7
*i7
)
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
,
303 int argc
, const char **argv
)
306 uint32 info_level
= 1;
307 PRINTER_INFO_CTR ctr
;
308 uint32 i
= 0, num_printers
;
313 printf("Usage: %s [level] [name]\n", argv
[0]);
318 info_level
= atoi(argv
[1]);
321 fstrcpy(name
, argv
[2]);
323 slprintf(name
, sizeof(name
)-1, "\\\\%s", cli
->desthost
);
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
)) {
335 printf ("No printers returned.\n");
339 for (i
= 0; i
< num_printers
; i
++) {
342 display_print_info_0(&ctr
.printers_0
[i
]);
345 display_print_info_1(&ctr
.printers_1
[i
]);
348 display_print_info_2(&ctr
.printers_2
[i
]);
351 display_print_info_3(&ctr
.printers_3
[i
]);
354 printf("unknown info level %d\n", info_level
);
364 /****************************************************************************
365 ****************************************************************************/
367 static void display_port_info_1(PORT_INFO_1
*i1
)
371 rpcstr_pull(buffer
, i1
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
372 printf("\tPort Name:\t[%s]\n", buffer
);
375 /****************************************************************************
376 ****************************************************************************/
378 static void display_port_info_2(PORT_INFO_2
*i2
)
382 rpcstr_pull(buffer
, i2
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
383 printf("\tPort Name:\t[%s]\n", buffer
);
384 rpcstr_pull(buffer
, i2
->monitor_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
386 printf("\tMonitor Name:\t[%s]\n", buffer
);
387 rpcstr_pull(buffer
, i2
->description
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
389 printf("\tDescription:\t[%s]\n", buffer
);
390 printf("\tPort Type:\t" );
391 if ( i2
->port_type
) {
392 int comma
= 0; /* hack */
394 if ( i2
->port_type
& PORT_TYPE_READ
) {
398 if ( i2
->port_type
& PORT_TYPE_WRITE
) {
399 printf( "%sWrite", comma
? ", " : "" );
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
? ", " : "" );
408 if ( i2
->port_type
& PORT_TYPE_NET_ATTACHED
) {
409 printf( "%sNet-Attached", comma
? ", " : "" );
413 printf( "[Unset]\n" );
415 printf("\tReserved:\t[%d]\n", i2
->reserved
);
419 /****************************************************************************
420 ****************************************************************************/
422 static WERROR
cmd_spoolss_enum_ports(struct cli_state
*cli
,
423 TALLOC_CTX
*mem_ctx
, int argc
,
427 uint32 info_level
= 1;
432 printf("Usage: %s [level]\n", argv
[0]);
437 info_level
= atoi(argv
[1]);
439 /* Enumerate ports */
443 result
= cli_spoolss_enum_ports(cli
, mem_ctx
, info_level
, &returned
, &ctr
);
445 if (W_ERROR_IS_OK(result
)) {
448 for (i
= 0; i
< returned
; i
++) {
449 switch (info_level
) {
451 display_port_info_1(&ctr
.port
.info_1
[i
]);
454 display_port_info_2(&ctr
.port
.info_2
[i
]);
457 printf("unknown info level %d\n", info_level
);
466 /****************************************************************************
467 ****************************************************************************/
469 static WERROR
cmd_spoolss_setprinter(struct cli_state
*cli
,
471 int argc
, const char **argv
)
475 uint32 info_level
= 2;
476 BOOL opened_hnd
= False
;
477 PRINTER_INFO_CTR ctr
;
483 if (argc
== 1 || argc
> 3) {
484 printf("Usage: %s printername comment\n", argv
[0]);
489 /* Open a printer handle */
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
,
504 if (!W_ERROR_IS_OK(result
))
509 /* Get printer info */
510 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
512 if (!W_ERROR_IS_OK(result
))
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");
527 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
532 /****************************************************************************
533 ****************************************************************************/
535 static WERROR
cmd_spoolss_setprintername(struct cli_state
*cli
,
537 int argc
, const char **argv
)
541 uint32 info_level
= 2;
542 BOOL opened_hnd
= False
;
543 PRINTER_INFO_CTR ctr
;
549 if (argc
== 1 || argc
> 3) {
550 printf("Usage: %s printername new_printername\n", argv
[0]);
555 /* Open a printer handle */
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
,
570 if (!W_ERROR_IS_OK(result
))
575 /* Get printer info */
576 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
578 if (!W_ERROR_IS_OK(result
))
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");
592 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
597 /****************************************************************************
598 ****************************************************************************/
600 static WERROR
cmd_spoolss_getprinter(struct cli_state
*cli
,
602 int argc
, const char **argv
)
606 uint32 info_level
= 1;
607 BOOL opened_hnd
= False
;
608 PRINTER_INFO_CTR ctr
;
613 if (argc
== 1 || argc
> 3) {
614 printf("Usage: %s <printername> [level]\n", argv
[0]);
618 /* Open a printer handle */
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
))
639 /* Get printer info */
641 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
643 if (!W_ERROR_IS_OK(result
))
646 /* Display printer info */
648 switch (info_level
) {
650 display_print_info_0(ctr
.printers_0
);
653 display_print_info_1(ctr
.printers_1
);
656 display_print_info_2(ctr
.printers_2
);
659 display_print_info_3(ctr
.printers_3
);
662 display_print_info_7(ctr
.printers_7
);
665 printf("unknown info level %d\n", info_level
);
671 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
676 /****************************************************************************
677 ****************************************************************************/
679 static void display_reg_value(REGISTRY_VALUE value
)
685 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
686 *((uint32
*) value
.data_p
));
689 rpcstr_pull(text
, value
.data_p
, sizeof(text
), value
.size
,
691 printf("%s: REG_SZ: %s\n", value
.valuename
, text
);
694 printf("%s: REG_BINARY: unknown length value not displayed\n",
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,
705 printf(" %s\n", text
);
706 curstr
+= strlen(text
) + 1;
711 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
716 /****************************************************************************
717 ****************************************************************************/
719 static WERROR
cmd_spoolss_getprinterdata(struct cli_state
*cli
,
721 int argc
, const char **argv
)
725 BOOL opened_hnd
= False
;
729 const char *valuename
;
730 REGISTRY_VALUE value
;
733 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
734 printf("<printername> of . queries print server\n");
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
);
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
))
761 /* Get printer info */
763 result
= cli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
765 if (!W_ERROR_IS_OK(result
))
768 /* Display printer data */
770 fstrcpy(value
.valuename
, valuename
);
771 display_reg_value(value
);
776 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
781 /****************************************************************************
782 ****************************************************************************/
784 static WERROR
cmd_spoolss_getprinterdataex(struct cli_state
*cli
,
786 int argc
, const char **argv
)
790 BOOL opened_hnd
= False
;
794 const char *valuename
, *keyname
;
795 REGISTRY_VALUE value
;
798 printf("Usage: %s <printername> <keyname> <valuename>\n",
800 printf("<printername> of . queries print server\n");
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
);
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
))
828 /* Get printer info */
830 result
= cli_spoolss_getprinterdataex(cli
, mem_ctx
, &pol
, keyname
,
833 if (!W_ERROR_IS_OK(result
))
836 /* Display printer data */
838 fstrcpy(value
.valuename
, valuename
);
839 display_reg_value(value
);
844 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
849 /****************************************************************************
850 ****************************************************************************/
852 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
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
);
866 /****************************************************************************
867 ****************************************************************************/
869 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
872 fstring architecture
;
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
);
896 /****************************************************************************
897 ****************************************************************************/
899 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
902 fstring architecture
= "";
903 fstring driverpath
= "";
904 fstring datafile
= "";
905 fstring configfile
= "";
906 fstring helpfile
= "";
907 fstring dependentfiles
= "";
908 fstring monitorname
= "";
909 fstring defaultdatatype
= "";
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
);
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
);
953 printf ("\tMonitorname: [%s]\n", monitorname
);
954 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
959 /****************************************************************************
960 ****************************************************************************/
962 static WERROR
cmd_spoolss_getdriver(struct cli_state
*cli
,
964 int argc
, const char **argv
)
968 uint32 info_level
= 3;
969 BOOL opened_hnd
= False
;
970 PRINTER_DRIVER_CTR ctr
;
975 BOOL success
= False
;
977 if ((argc
== 1) || (argc
> 3))
979 printf("Usage: %s <printername> [level]\n", argv
[0]);
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]);
989 info_level
= atoi(argv
[2]);
991 /* Open a printer handle */
993 werror
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
995 servername
, user
, &pol
);
997 if (!W_ERROR_IS_OK(werror
)) {
998 printf("Error opening printer handle for %s!\n", printername
);
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
,
1012 if (!W_ERROR_IS_OK(werror
))
1015 /* need at least one success */
1019 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1021 switch (info_level
) {
1023 display_print_driver_1 (ctr
.info1
);
1026 display_print_driver_2 (ctr
.info2
);
1029 display_print_driver_3 (ctr
.info3
);
1032 printf("unknown info level %d\n", info_level
);
1040 cli_spoolss_close_printer (cli
, mem_ctx
, &pol
);
1048 /****************************************************************************
1049 ****************************************************************************/
1051 static WERROR
cmd_spoolss_enum_drivers(struct cli_state
*cli
,
1052 TALLOC_CTX
*mem_ctx
,
1053 int argc
, const char **argv
)
1056 uint32 info_level
= 1;
1057 PRINTER_DRIVER_CTR ctr
;
1063 printf("Usage: enumdrivers [level]\n");
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
) )
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
);
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
));
1099 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1104 for (j
=0; j
< returned
; j
++) {
1105 display_print_driver_1 (&(ctr
.info1
[j
]));
1109 for (j
=0; j
< returned
; j
++) {
1110 display_print_driver_2 (&(ctr
.info2
[j
]));
1114 for (j
=0; j
< returned
; j
++) {
1115 display_print_driver_3 (&(ctr
.info3
[j
]));
1119 printf("unknown info level %d\n", info_level
);
1127 /****************************************************************************
1128 ****************************************************************************/
1130 static void display_printdriverdir_1(DRIVER_DIRECTORY_1
*i1
)
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
)
1150 DRIVER_DIRECTORY_CTR ctr
;
1153 printf("Usage: %s [environment]\n", argv
[0]);
1157 /* Get the arguments need to open the printer handle */
1160 fstrcpy (env
, argv
[1]);
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
);
1174 /****************************************************************************
1175 ****************************************************************************/
1177 void set_drv_info_3_env (DRIVER_INFO_3
*info
, const char *arch
)
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
);
1192 if (archi_table
[i
].long_archi
== NULL
)
1194 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
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
)
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)
1217 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0))
1221 init_unistr(dest
, 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
,
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 */
1252 /* begin to strip out each filename */
1253 str
= strtok(str
, ",");
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
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"));
1270 for (i
=0; i
<len
; i
++)
1272 SSVAL(&info
->dependentfiles
[i
], 0, str2
[i
]);
1274 info
->dependentfiles
[len
] = '\0';
1280 /****************************************************************************
1281 ****************************************************************************/
1283 static WERROR
cmd_spoolss_addprinterdriver(struct cli_state
*cli
,
1284 TALLOC_CTX
*mem_ctx
,
1285 int argc
, const char **argv
)
1289 PRINTER_DRIVER_CTR ctr
;
1290 DRIVER_INFO_3 info3
;
1292 fstring driver_name
;
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");
1307 /* Fill in the DRIVER_INFO_3 struct */
1309 if (!(arch
= cmd_spoolss_get_short_archi(argv
[1])))
1311 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1312 return WERR_INVALID_PARAM
;
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. */
1329 info3
.version
= atoi(argv
[3]);
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",
1347 /****************************************************************************
1348 ****************************************************************************/
1350 static WERROR
cmd_spoolss_addprinterex(struct cli_state
*cli
,
1351 TALLOC_CTX
*mem_ctx
,
1352 int argc
, const char **argv
)
1356 PRINTER_INFO_CTR ctr
;
1357 PRINTER_INFO_2 info2
;
1360 /* parse the command arguements */
1363 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1367 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1368 strupper_m(servername
);
1370 /* Fill in the DRIVER_INFO_2 struct */
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
;
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..
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]);
1405 /****************************************************************************
1406 ****************************************************************************/
1408 static WERROR
cmd_spoolss_setdriver(struct cli_state
*cli
,
1409 TALLOC_CTX
*mem_ctx
,
1410 int argc
, const char **argv
)
1415 BOOL opened_hnd
= False
;
1416 PRINTER_INFO_CTR ctr
;
1417 PRINTER_INFO_2 info2
;
1422 /* parse the command arguements */
1425 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
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
, "",
1438 servername
, user
, &pol
);
1440 if (!W_ERROR_IS_OK(result
))
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");
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");
1468 printf("Succesfully set %s to driver %s.\n", argv
[1], argv
[2]);
1474 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
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
;
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]);
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
))
1512 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
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
));
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
);
1538 /****************************************************************************
1539 ****************************************************************************/
1541 static WERROR
cmd_spoolss_deletedriver(struct cli_state
*cli
,
1542 TALLOC_CTX
*mem_ctx
,
1543 int argc
, const char **argv
)
1549 /* parse the command arguements */
1552 printf ("Usage: %s <driver>\n", argv
[0]);
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
,
1575 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1576 archi_table
[i
].long_archi
);
1583 /****************************************************************************
1584 ****************************************************************************/
1586 static WERROR
cmd_spoolss_getprintprocdir(struct cli_state
*cli
,
1587 TALLOC_CTX
*mem_ctx
,
1588 int argc
, const char **argv
)
1591 char *servername
= NULL
, *environment
= NULL
;
1594 /* parse the command arguements */
1596 printf ("Usage: %s [environment]\n", argv
[0]);
1600 if (asprintf(&servername
, "\\\\%s", cli
->desthost
) < 0)
1602 strupper_m(servername
);
1604 if (asprintf(&environment
, "%s", (argc
== 2) ? argv
[1] :
1605 PRINTER_DRIVER_ARCHITECTURE
) < 0) {
1606 SAFE_FREE(servername
);
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
);
1622 /****************************************************************************
1623 ****************************************************************************/
1625 static WERROR
cmd_spoolss_addform(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1626 int argc
, const char **argv
)
1630 char *servername
= NULL
, *printername
= NULL
;
1632 BOOL got_handle
= False
;
1634 /* Parse the command arguements */
1637 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
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
, "",
1649 servername
, cli
->user_name
, &handle
);
1651 if (!W_ERROR_IS_OK(werror
))
1656 /* Dummy up some values for the form data */
1658 form
.flags
= FORM_USER
;
1659 form
.size_x
= form
.size_y
= 100;
1665 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1670 werror
= cli_spoolss_addform(cli
, mem_ctx
, &handle
, 1, &form
);
1674 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1676 SAFE_FREE(servername
);
1677 SAFE_FREE(printername
);
1682 /****************************************************************************
1683 ****************************************************************************/
1685 static WERROR
cmd_spoolss_setform(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1686 int argc
, const char **argv
)
1690 char *servername
= NULL
, *printername
= NULL
;
1692 BOOL got_handle
= False
;
1694 /* Parse the command arguements */
1697 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
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
))
1716 /* Dummy up some values for the form data */
1718 form
.flags
= FORM_PRINTER
;
1719 form
.size_x
= form
.size_y
= 100;
1725 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1729 werror
= cli_spoolss_setform(cli
, mem_ctx
, &handle
, 1, argv
[2], &form
);
1733 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1735 SAFE_FREE(servername
);
1736 SAFE_FREE(printername
);
1741 /****************************************************************************
1742 ****************************************************************************/
1744 static const char *get_form_flag(int form_flag
)
1746 switch (form_flag
) {
1750 return "FORM_BUILTIN";
1752 return "FORM_PRINTER";
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
);
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
)
1787 char *servername
= NULL
, *printername
= NULL
;
1789 BOOL got_handle
= False
;
1791 /* Parse the command arguements */
1794 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
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
))
1815 werror
= cli_spoolss_getform(cli
, mem_ctx
, &handle
, argv
[2], 1, &form
);
1817 if (!W_ERROR_IS_OK(werror
))
1820 display_form(&form
);
1824 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1826 SAFE_FREE(servername
);
1827 SAFE_FREE(printername
);
1832 /****************************************************************************
1833 ****************************************************************************/
1835 static WERROR
cmd_spoolss_deleteform(struct cli_state
*cli
,
1836 TALLOC_CTX
*mem_ctx
, int argc
,
1841 char *servername
= NULL
, *printername
= NULL
;
1842 BOOL got_handle
= False
;
1844 /* Parse the command arguements */
1847 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
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
))
1866 /* Delete the form */
1868 werror
= cli_spoolss_deleteform(cli
, mem_ctx
, &handle
, argv
[2]);
1872 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1874 SAFE_FREE(servername
);
1875 SAFE_FREE(printername
);
1880 /****************************************************************************
1881 ****************************************************************************/
1883 static WERROR
cmd_spoolss_enum_forms(struct cli_state
*cli
,
1884 TALLOC_CTX
*mem_ctx
, int argc
,
1889 char *servername
= NULL
, *printername
= NULL
;
1890 BOOL got_handle
= False
;
1891 uint32 needed
, offered
, num_forms
, level
= 1, i
;
1894 /* Parse the command arguements */
1897 printf ("Usage: %s <printer>\n", argv
[0]);
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
))
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
))
1924 /* Display output */
1926 for (i
= 0; i
< num_forms
; i
++) {
1928 display_form(&forms
[i
]);
1934 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1936 SAFE_FREE(servername
);
1937 SAFE_FREE(printername
);
1942 /****************************************************************************
1943 ****************************************************************************/
1945 static WERROR
cmd_spoolss_setprinterdata(struct cli_state
*cli
,
1946 TALLOC_CTX
*mem_ctx
,
1947 int argc
, const char **argv
)
1950 fstring servername
, printername
, user
;
1952 BOOL opened_hnd
= False
;
1953 PRINTER_INFO_CTR ctr
;
1954 PRINTER_INFO_0 info
;
1955 REGISTRY_VALUE value
;
1958 /* parse the command arguements */
1960 printf ("Usage: %s <printer> <value> <data>\n", argv
[0]);
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
,
1973 if (!W_ERROR_IS_OK(result
))
1978 ctr
.printers_0
= &info
;
1980 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
1982 if (!W_ERROR_IS_OK(result
))
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]);
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
))
2009 printf("%s\n", timestring(True
));
2010 printf("\tchange_id (after set)\t:[0x%x]\n", info
.change_id
);
2015 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
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
,
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
,
2070 uint32 needed
, offered
, level
= 1, num_jobs
, i
;
2071 BOOL got_hnd
= False
;
2072 pstring printername
;
2073 fstring servername
, user
;
2077 if (argc
< 2 || argc
> 3) {
2078 printf("Usage: %s printername [level]\n", argv
[0]);
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
))
2103 /* Enumerate ports */
2105 offered
= needed
= 0;
2106 result
= cli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2109 if (!W_ERROR_IS_OK(result
))
2112 for (i
= 0; i
< num_jobs
; i
++) {
2115 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2118 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2121 d_printf("unknown info level %d\n", level
);
2128 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2133 /****************************************************************************
2134 ****************************************************************************/
2136 static WERROR
cmd_spoolss_enum_data( struct cli_state
*cli
,
2137 TALLOC_CTX
*mem_ctx
, int argc
,
2141 uint32 i
=0, val_needed
, data_needed
;
2142 BOOL got_hnd
= False
;
2143 pstring printername
;
2144 fstring servername
, user
;
2148 printf("Usage: %s printername\n", argv
[0]);
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
))
2170 /* Enumerate data */
2172 result
= cli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2173 &val_needed
, &data_needed
,
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
);
2188 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2193 /****************************************************************************
2194 ****************************************************************************/
2196 static WERROR
cmd_spoolss_enum_data_ex( struct cli_state
*cli
,
2197 TALLOC_CTX
*mem_ctx
, int argc
,
2202 BOOL got_hnd
= False
;
2203 pstring printername
;
2204 fstring servername
, user
;
2205 const char *keyname
= NULL
;
2210 printf("Usage: %s printername <keyname>\n", argv
[0]);
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
))
2234 /* Enumerate subkeys */
2236 result
= cli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, &ctr
);
2238 if (!W_ERROR_IS_OK(result
))
2241 for (i
=0; i
< ctr
.num_values
; i
++) {
2242 display_reg_value(*(ctr
.values
[i
]));
2245 regval_ctr_destroy(&ctr
);
2249 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2254 /****************************************************************************
2255 ****************************************************************************/
2257 static WERROR
cmd_spoolss_enum_printerkey( struct cli_state
*cli
,
2258 TALLOC_CTX
*mem_ctx
, int argc
,
2262 BOOL got_hnd
= False
;
2263 pstring printername
;
2264 fstring servername
, user
;
2265 const char *keyname
= NULL
;
2267 uint16
*keylist
= NULL
, *curkey
;
2269 if (argc
< 2 || argc
> 3) {
2270 printf("Usage: %s printername [keyname]\n", argv
[0]);
2279 /* Open printer handle */
2281 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2282 strupper_m(servername
);
2283 fstrcpy(user
, cli
->user_name
);
2284 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->desthost
);
2285 strupper_m(printername
);
2286 pstrcat(printername
, argv
[1]);
2288 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2289 "", MAXIMUM_ALLOWED_ACCESS
,
2290 servername
, user
, &hnd
);
2292 if (!W_ERROR_IS_OK(result
))
2297 /* Enumerate subkeys */
2299 result
= cli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, NULL
, NULL
);
2301 if (!W_ERROR_IS_OK(result
))
2305 while (*curkey
!= 0) {
2307 rpcstr_pull(subkey
, curkey
, sizeof(subkey
), -1,
2309 printf("%s\n", subkey
);
2310 curkey
+= strlen(subkey
) + 1;
2317 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2322 /****************************************************************************
2323 ****************************************************************************/
2325 static WERROR
cmd_spoolss_rffpcnex(struct cli_state
*cli
,
2326 TALLOC_CTX
*mem_ctx
, int argc
,
2329 fstring servername
, printername
;
2331 BOOL got_hnd
= False
;
2333 SPOOL_NOTIFY_OPTION option
;
2336 printf("Usage: %s printername\n", argv
[0]);
2343 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", cli
->desthost
);
2344 strupper_m(servername
);
2346 slprintf(printername
, sizeof(printername
) - 1, "\\\\%s\\%s", cli
->desthost
,
2348 strupper_m(printername
);
2350 result
= cli_spoolss_open_printer_ex(
2351 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
2352 servername
, cli
->user_name
, &hnd
);
2354 if (!W_ERROR_IS_OK(result
)) {
2355 printf("Error opening %s\n", argv
[1]);
2361 /* Create spool options */
2363 ZERO_STRUCT(option
);
2366 option
.option_type_ptr
= 1;
2367 option
.count
= option
.ctr
.count
= 2;
2369 option
.ctr
.type
= TALLOC_ARRAY(mem_ctx
, SPOOL_NOTIFY_OPTION_TYPE
, 2);
2371 ZERO_STRUCT(option
.ctr
.type
[0]);
2372 option
.ctr
.type
[0].type
= PRINTER_NOTIFY_TYPE
;
2373 option
.ctr
.type
[0].count
= option
.ctr
.type
[0].count2
= 1;
2374 option
.ctr
.type
[0].fields_ptr
= 1;
2375 option
.ctr
.type
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2377 ZERO_STRUCT(option
.ctr
.type
[1]);
2378 option
.ctr
.type
[1].type
= JOB_NOTIFY_TYPE
;
2379 option
.ctr
.type
[1].count
= option
.ctr
.type
[1].count2
= 1;
2380 option
.ctr
.type
[1].fields_ptr
= 1;
2381 option
.ctr
.type
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2385 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", myhostname());
2386 strupper_m(servername
);
2388 result
= cli_spoolss_rffpcnex(
2389 cli
, mem_ctx
, &hnd
, 0, 0, servername
, 123, &option
);
2391 if (!W_ERROR_IS_OK(result
)) {
2392 printf("Error rffpcnex %s\n", argv
[1]);
2398 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2403 /* List of commands exported by this module */
2404 struct cmd_set spoolss_commands
[] = {
2408 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, PI_SPOOLSS
, "Add a print driver", "" },
2409 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, PI_SPOOLSS
, "Add a printer", "" },
2410 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, PI_SPOOLSS
, "Delete a printer driver", "" },
2411 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, PI_SPOOLSS
, "Delete a printer driver with files", "" },
2412 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, PI_SPOOLSS
, "Enumerate printer data", "" },
2413 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, PI_SPOOLSS
, "Enumerate printer data for a key", "" },
2414 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, PI_SPOOLSS
, "Enumerate printer keys", "" },
2415 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, PI_SPOOLSS
, "Enumerate print jobs", "" },
2416 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, PI_SPOOLSS
, "Enumerate printer ports", "" },
2417 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, PI_SPOOLSS
, "Enumerate installed printer drivers", "" },
2418 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, PI_SPOOLSS
, "Enumerate printers", "" },
2419 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, PI_SPOOLSS
, "Get print driver data", "" },
2420 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, PI_SPOOLSS
, "Get printer driver data with keyname", ""},
2421 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, PI_SPOOLSS
, "Get print driver information", "" },
2422 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, PI_SPOOLSS
, "Get print driver upload directory", "" },
2423 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, PI_SPOOLSS
, "Get printer info", "" },
2424 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, PI_SPOOLSS
, "Open printer handle", "" },
2425 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, PI_SPOOLSS
, "Set printer driver", "" },
2426 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, PI_SPOOLSS
, "Get print processor directory", "" },
2427 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, PI_SPOOLSS
, "Add form", "" },
2428 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, PI_SPOOLSS
, "Set form", "" },
2429 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, PI_SPOOLSS
, "Get form", "" },
2430 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, PI_SPOOLSS
, "Delete form", "" },
2431 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, PI_SPOOLSS
, "Enumerate forms", "" },
2432 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, PI_SPOOLSS
, "Set printer comment", "" },
2433 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, PI_SPOOLSS
, "Set printername", "" },
2434 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, PI_SPOOLSS
, "Set REG_SZ printer data", "" },
2435 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, PI_SPOOLSS
, "Rffpcnex test", "" },