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 char *hex
= hex_encode(NULL
, value
.data_p
, value
.size
);
696 printf("%s: REG_BINARY:", value
.valuename
);
698 for (i
=0; i
<len
; i
++) {
699 if (hex
[i
] == '\0') {
712 uint16
*curstr
= (uint16
*) value
.data_p
;
713 uint8
*start
= value
.data_p
;
714 printf("%s: REG_MULTI_SZ:\n", value
.valuename
);
715 while (((uint8
*) curstr
< start
+ value
.size
)) {
716 rpcstr_pull(text
, curstr
, sizeof(text
), -1,
718 printf(" %s\n", *text
!= 0 ? text
: "NULL");
719 curstr
+= strlen(text
) + 1;
724 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
729 /****************************************************************************
730 ****************************************************************************/
732 static WERROR
cmd_spoolss_getprinterdata(struct cli_state
*cli
,
734 int argc
, const char **argv
)
738 BOOL opened_hnd
= False
;
742 const char *valuename
;
743 REGISTRY_VALUE value
;
746 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
747 printf("<printername> of . queries print server\n");
752 /* Open a printer handle */
754 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
755 strupper_m(servername
);
756 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
757 fstrcpy(printername
, servername
);
759 slprintf(printername
, sizeof(servername
)-1, "%s\\%s",
760 servername
, argv
[1]);
761 fstrcpy(user
, cli
->user_name
);
763 /* get a printer handle */
765 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
766 "", MAXIMUM_ALLOWED_ACCESS
,
767 servername
, user
, &pol
);
769 if (!W_ERROR_IS_OK(result
))
774 /* Get printer info */
776 result
= cli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
778 if (!W_ERROR_IS_OK(result
))
781 /* Display printer data */
783 fstrcpy(value
.valuename
, valuename
);
784 display_reg_value(value
);
789 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
794 /****************************************************************************
795 ****************************************************************************/
797 static WERROR
cmd_spoolss_getprinterdataex(struct cli_state
*cli
,
799 int argc
, const char **argv
)
803 BOOL opened_hnd
= False
;
807 const char *valuename
, *keyname
;
808 REGISTRY_VALUE value
;
811 printf("Usage: %s <printername> <keyname> <valuename>\n",
813 printf("<printername> of . queries print server\n");
819 /* Open a printer handle */
821 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
822 strupper_m(servername
);
823 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
824 fstrcpy(printername
, servername
);
826 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
827 servername
, argv
[1]);
828 fstrcpy(user
, cli
->user_name
);
830 /* get a printer handle */
832 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
833 "", MAXIMUM_ALLOWED_ACCESS
,
834 servername
, user
, &pol
);
836 if (!W_ERROR_IS_OK(result
))
841 /* Get printer info */
843 result
= cli_spoolss_getprinterdataex(cli
, mem_ctx
, &pol
, keyname
,
846 if (!W_ERROR_IS_OK(result
))
849 /* Display printer data */
851 fstrcpy(value
.valuename
, valuename
);
852 display_reg_value(value
);
857 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
862 /****************************************************************************
863 ****************************************************************************/
865 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
871 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
873 printf ("Printer Driver Info 1:\n");
874 printf ("\tDriver Name: [%s]\n\n", name
);
879 /****************************************************************************
880 ****************************************************************************/
882 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
885 fstring architecture
;
892 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
893 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
894 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
895 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
896 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
898 printf ("Printer Driver Info 2:\n");
899 printf ("\tVersion: [%x]\n", i1
->version
);
900 printf ("\tDriver Name: [%s]\n", name
);
901 printf ("\tArchitecture: [%s]\n", architecture
);
902 printf ("\tDriver Path: [%s]\n", driverpath
);
903 printf ("\tDatafile: [%s]\n", datafile
);
904 printf ("\tConfigfile: [%s]\n\n", configfile
);
909 /****************************************************************************
910 ****************************************************************************/
912 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
915 fstring architecture
= "";
916 fstring driverpath
= "";
917 fstring datafile
= "";
918 fstring configfile
= "";
919 fstring helpfile
= "";
920 fstring dependentfiles
= "";
921 fstring monitorname
= "";
922 fstring defaultdatatype
= "";
930 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
931 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
932 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
933 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
934 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
935 rpcstr_pull(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
), -1, STR_TERMINATE
);
936 rpcstr_pull(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
), -1, STR_TERMINATE
);
937 rpcstr_pull(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
), -1, STR_TERMINATE
);
939 printf ("Printer Driver Info 3:\n");
940 printf ("\tVersion: [%x]\n", i1
->version
);
941 printf ("\tDriver Name: [%s]\n",name
);
942 printf ("\tArchitecture: [%s]\n", architecture
);
943 printf ("\tDriver Path: [%s]\n", driverpath
);
944 printf ("\tDatafile: [%s]\n", datafile
);
945 printf ("\tConfigfile: [%s]\n", configfile
);
946 printf ("\tHelpfile: [%s]\n\n", helpfile
);
950 rpcstr_pull(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
), -1, STR_TERMINATE
);
952 length
+=strlen(dependentfiles
)+1;
954 if (strlen(dependentfiles
) > 0)
956 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
966 printf ("\tMonitorname: [%s]\n", monitorname
);
967 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
972 /****************************************************************************
973 ****************************************************************************/
975 static WERROR
cmd_spoolss_getdriver(struct cli_state
*cli
,
977 int argc
, const char **argv
)
981 uint32 info_level
= 3;
982 BOOL opened_hnd
= False
;
983 PRINTER_DRIVER_CTR ctr
;
988 BOOL success
= False
;
990 if ((argc
== 1) || (argc
> 3))
992 printf("Usage: %s <printername> [level]\n", argv
[0]);
996 /* get the arguments need to open the printer handle */
997 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
998 strupper_m(servername
);
999 fstrcpy(user
, cli
->user_name
);
1000 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1002 info_level
= atoi(argv
[2]);
1004 /* Open a printer handle */
1006 werror
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1008 servername
, user
, &pol
);
1010 if (!W_ERROR_IS_OK(werror
)) {
1011 printf("Error opening printer handle for %s!\n", printername
);
1017 /* loop through and print driver info level for each architecture */
1019 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1021 werror
= cli_spoolss_getprinterdriver( cli
, mem_ctx
, &pol
, info_level
,
1022 archi_table
[i
].long_archi
, archi_table
[i
].version
,
1025 if (!W_ERROR_IS_OK(werror
))
1028 /* need at least one success */
1032 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1034 switch (info_level
) {
1036 display_print_driver_1 (ctr
.info1
);
1039 display_print_driver_2 (ctr
.info2
);
1042 display_print_driver_3 (ctr
.info3
);
1045 printf("unknown info level %d\n", info_level
);
1053 cli_spoolss_close_printer (cli
, mem_ctx
, &pol
);
1061 /****************************************************************************
1062 ****************************************************************************/
1064 static WERROR
cmd_spoolss_enum_drivers(struct cli_state
*cli
,
1065 TALLOC_CTX
*mem_ctx
,
1066 int argc
, const char **argv
)
1069 uint32 info_level
= 1;
1070 PRINTER_DRIVER_CTR ctr
;
1076 printf("Usage: enumdrivers [level]\n");
1081 info_level
= atoi(argv
[1]);
1084 /* loop through and print driver info level for each architecture */
1085 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++)
1087 /* check to see if we already asked for this architecture string */
1089 if ( i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
) )
1092 werror
= cli_spoolss_enumprinterdrivers(
1093 cli
, mem_ctx
, info_level
,
1094 archi_table
[i
].long_archi
, &returned
, &ctr
);
1096 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1097 printf ("Server does not support environment [%s]\n",
1098 archi_table
[i
].long_archi
);
1106 if (!W_ERROR_IS_OK(werror
)) {
1107 printf ("Error getting driver for environment [%s] - %d\n",
1108 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1112 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1117 for (j
=0; j
< returned
; j
++) {
1118 display_print_driver_1 (&(ctr
.info1
[j
]));
1122 for (j
=0; j
< returned
; j
++) {
1123 display_print_driver_2 (&(ctr
.info2
[j
]));
1127 for (j
=0; j
< returned
; j
++) {
1128 display_print_driver_3 (&(ctr
.info3
[j
]));
1132 printf("unknown info level %d\n", info_level
);
1140 /****************************************************************************
1141 ****************************************************************************/
1143 static void display_printdriverdir_1(DRIVER_DIRECTORY_1
*i1
)
1149 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
1151 printf ("\tDirectory Name:[%s]\n", name
);
1154 /****************************************************************************
1155 ****************************************************************************/
1157 static WERROR
cmd_spoolss_getdriverdir(struct cli_state
*cli
,
1158 TALLOC_CTX
*mem_ctx
,
1159 int argc
, const char **argv
)
1163 DRIVER_DIRECTORY_CTR ctr
;
1166 printf("Usage: %s [environment]\n", argv
[0]);
1170 /* Get the arguments need to open the printer handle */
1173 fstrcpy (env
, argv
[1]);
1175 fstrcpy (env
, "Windows NT x86");
1177 /* Get the directory. Only use Info level 1 */
1179 result
= cli_spoolss_getprinterdriverdir(cli
, mem_ctx
, 1, env
, &ctr
);
1181 if (W_ERROR_IS_OK(result
))
1182 display_printdriverdir_1(ctr
.info1
);
1187 /****************************************************************************
1188 ****************************************************************************/
1190 void set_drv_info_3_env (DRIVER_INFO_3
*info
, const char *arch
)
1195 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1197 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1199 info
->version
= archi_table
[i
].version
;
1200 init_unistr (&info
->architecture
, archi_table
[i
].long_archi
);
1205 if (archi_table
[i
].long_archi
== NULL
)
1207 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1214 /**************************************************************************
1215 wrapper for strtok to get the next parameter from a delimited list.
1216 Needed to handle the empty parameter string denoted by "NULL"
1217 *************************************************************************/
1219 static char* get_driver_3_param (char* str
, const char* delim
, UNISTR
* dest
)
1223 /* get the next token */
1224 ptr
= strtok(str
, delim
);
1226 /* a string of 'NULL' is used to represent an empty
1227 parameter because two consecutive delimiters
1228 will not return an empty string. See man strtok(3)
1230 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0))
1234 init_unistr(dest
, ptr
);
1239 /********************************************************************************
1240 fill in the members of a DRIVER_INFO_3 struct using a character
1241 string in the form of
1242 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1243 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1244 <Default Data Type>:<Comma Separated list of Files>
1245 *******************************************************************************/
1246 static BOOL
init_drv_info_3_members ( TALLOC_CTX
*mem_ctx
, DRIVER_INFO_3
*info
,
1252 /* fill in the UNISTR fields */
1253 str
= get_driver_3_param (args
, ":", &info
->name
);
1254 str
= get_driver_3_param (NULL
, ":", &info
->driverpath
);
1255 str
= get_driver_3_param (NULL
, ":", &info
->datafile
);
1256 str
= get_driver_3_param (NULL
, ":", &info
->configfile
);
1257 str
= get_driver_3_param (NULL
, ":", &info
->helpfile
);
1258 str
= get_driver_3_param (NULL
, ":", &info
->monitorname
);
1259 str
= get_driver_3_param (NULL
, ":", &info
->defaultdatatype
);
1261 /* <Comma Separated List of Dependent Files> */
1262 str2
= get_driver_3_param (NULL
, ":", NULL
); /* save the beginning of the string */
1265 /* begin to strip out each filename */
1266 str
= strtok(str
, ",");
1270 /* keep a cumlative count of the str lengths */
1271 len
+= strlen(str
)+1;
1272 str
= strtok(NULL
, ",");
1275 /* allocate the space; add one extra slot for a terminating NULL.
1276 Each filename is NULL terminated and the end contains a double
1278 if ((info
->dependentfiles
=TALLOC_ARRAY(mem_ctx
, uint16
, len
+1)) == NULL
)
1280 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1283 for (i
=0; i
<len
; i
++)
1285 SSVAL(&info
->dependentfiles
[i
], 0, str2
[i
]);
1287 info
->dependentfiles
[len
] = '\0';
1293 /****************************************************************************
1294 ****************************************************************************/
1296 static WERROR
cmd_spoolss_addprinterdriver(struct cli_state
*cli
,
1297 TALLOC_CTX
*mem_ctx
,
1298 int argc
, const char **argv
)
1302 PRINTER_DRIVER_CTR ctr
;
1303 DRIVER_INFO_3 info3
;
1305 fstring driver_name
;
1308 /* parse the command arguements */
1309 if (argc
!= 3 && argc
!= 4)
1311 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1312 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1313 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1314 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1315 printf ("\t[version]\n");
1320 /* Fill in the DRIVER_INFO_3 struct */
1322 if (!(arch
= cmd_spoolss_get_short_archi(argv
[1])))
1324 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1325 return WERR_INVALID_PARAM
;
1328 set_drv_info_3_env(&info3
, arch
);
1330 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1331 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1333 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1334 return WERR_INVALID_PARAM
;
1337 /* if printer driver version specified, override the default version
1338 * used by the architecture. This allows installation of Windows
1339 * 2000 (version 3) printer drivers. */
1342 info3
.version
= atoi(argv
[3]);
1347 result
= cli_spoolss_addprinterdriver (cli
, mem_ctx
, level
, &ctr
);
1349 if (W_ERROR_IS_OK(result
)) {
1350 rpcstr_pull(driver_name
, info3
.name
.buffer
,
1351 sizeof(driver_name
), -1, STR_TERMINATE
);
1352 printf ("Printer Driver %s successfully installed.\n",
1360 /****************************************************************************
1361 ****************************************************************************/
1363 static WERROR
cmd_spoolss_addprinterex(struct cli_state
*cli
,
1364 TALLOC_CTX
*mem_ctx
,
1365 int argc
, const char **argv
)
1369 PRINTER_INFO_CTR ctr
;
1370 PRINTER_INFO_2 info2
;
1373 /* parse the command arguements */
1376 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1380 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1381 strupper_m(servername
);
1383 /* Fill in the DRIVER_INFO_2 struct */
1386 init_unistr( &info2
.printername
, argv
[1]);
1387 init_unistr( &info2
.sharename
, argv
[2]);
1388 init_unistr( &info2
.drivername
, argv
[3]);
1389 init_unistr( &info2
.portname
, argv
[4]);
1390 init_unistr( &info2
.comment
, "Created by rpcclient");
1391 init_unistr( &info2
.printprocessor
, "winprint");
1392 init_unistr( &info2
.datatype
, "RAW");
1393 info2
.devmode
= NULL
;
1394 info2
.secdesc
= NULL
;
1395 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1397 info2
.defaultpriority
= 0;
1398 info2
.starttime
= 0;
1399 info2
.untiltime
= 0;
1401 /* These three fields must not be used by AddPrinter()
1402 as defined in the MS Platform SDK documentation..
1406 info2.averageppm = 0;
1409 ctr
.printers_2
= &info2
;
1410 result
= cli_spoolss_addprinterex (cli
, mem_ctx
, level
, &ctr
);
1412 if (W_ERROR_IS_OK(result
))
1413 printf ("Printer %s successfully installed.\n", argv
[1]);
1418 /****************************************************************************
1419 ****************************************************************************/
1421 static WERROR
cmd_spoolss_setdriver(struct cli_state
*cli
,
1422 TALLOC_CTX
*mem_ctx
,
1423 int argc
, const char **argv
)
1428 BOOL opened_hnd
= False
;
1429 PRINTER_INFO_CTR ctr
;
1430 PRINTER_INFO_2 info2
;
1435 /* parse the command arguements */
1438 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1442 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1443 strupper_m(servername
);
1444 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
1445 fstrcpy(user
, cli
->user_name
);
1447 /* Get a printer handle */
1449 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1451 servername
, user
, &pol
);
1453 if (!W_ERROR_IS_OK(result
))
1458 /* Get printer info */
1460 ZERO_STRUCT (info2
);
1461 ctr
.printers_2
= &info2
;
1463 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, level
, &ctr
);
1465 if (!W_ERROR_IS_OK(result
)) {
1466 printf ("Unable to retrieve printer information!\n");
1470 /* Set the printer driver */
1472 init_unistr(&ctr
.printers_2
->drivername
, argv
[2]);
1474 result
= cli_spoolss_setprinter(cli
, mem_ctx
, &pol
, level
, &ctr
, 0);
1476 if (!W_ERROR_IS_OK(result
)) {
1477 printf("SetPrinter call failed!\n");
1481 printf("Succesfully set %s to driver %s.\n", argv
[1], argv
[2]);
1487 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
1493 /****************************************************************************
1494 ****************************************************************************/
1496 static WERROR
cmd_spoolss_deletedriverex(struct cli_state
*cli
,
1497 TALLOC_CTX
*mem_ctx
,
1498 int argc
, const char **argv
)
1500 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1505 const char *arch
= NULL
;
1507 /* parse the command arguements */
1508 if (argc
< 2 || argc
> 4) {
1509 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1516 vers
= atoi (argv
[3]);
1519 /* delete the driver for all architectures */
1520 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1522 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1525 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1528 /* make the call to remove the driver */
1529 result
= cli_spoolss_deleteprinterdriverex(
1530 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1], archi_table
[i
].version
);
1532 if ( !W_ERROR_IS_OK(result
) )
1534 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1535 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1536 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, dos_errstr(result
));
1541 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1542 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1551 /****************************************************************************
1552 ****************************************************************************/
1554 static WERROR
cmd_spoolss_deletedriver(struct cli_state
*cli
,
1555 TALLOC_CTX
*mem_ctx
,
1556 int argc
, const char **argv
)
1562 /* parse the command arguements */
1565 printf ("Usage: %s <driver>\n", argv
[0]);
1569 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1570 strupper_m(servername
);
1572 /* delete the driver for all architectures */
1573 for (i
=0; archi_table
[i
].long_archi
; i
++)
1575 /* make the call to remove the driver */
1576 result
= cli_spoolss_deleteprinterdriver(
1577 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1]);
1579 if ( !W_ERROR_IS_OK(result
) ) {
1580 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1581 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1582 argv
[1], archi_table
[i
].long_archi
,
1588 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1589 archi_table
[i
].long_archi
);
1596 /****************************************************************************
1597 ****************************************************************************/
1599 static WERROR
cmd_spoolss_getprintprocdir(struct cli_state
*cli
,
1600 TALLOC_CTX
*mem_ctx
,
1601 int argc
, const char **argv
)
1604 char *servername
= NULL
, *environment
= NULL
;
1607 /* parse the command arguements */
1609 printf ("Usage: %s [environment]\n", argv
[0]);
1613 if (asprintf(&servername
, "\\\\%s", cli
->desthost
) < 0)
1615 strupper_m(servername
);
1617 if (asprintf(&environment
, "%s", (argc
== 2) ? argv
[1] :
1618 PRINTER_DRIVER_ARCHITECTURE
) < 0) {
1619 SAFE_FREE(servername
);
1623 result
= cli_spoolss_getprintprocessordirectory(
1624 cli
, mem_ctx
, servername
, environment
, procdir
);
1626 if (W_ERROR_IS_OK(result
))
1627 printf("%s\n", procdir
);
1629 SAFE_FREE(servername
);
1630 SAFE_FREE(environment
);
1635 /****************************************************************************
1636 ****************************************************************************/
1638 static WERROR
cmd_spoolss_addform(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1639 int argc
, const char **argv
)
1643 char *servername
= NULL
, *printername
= NULL
;
1645 BOOL got_handle
= False
;
1647 /* Parse the command arguements */
1650 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1654 /* Get a printer handle */
1656 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1657 strupper_m(servername
);
1658 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1660 werror
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1662 servername
, cli
->user_name
, &handle
);
1664 if (!W_ERROR_IS_OK(werror
))
1669 /* Dummy up some values for the form data */
1671 form
.flags
= FORM_USER
;
1672 form
.size_x
= form
.size_y
= 100;
1678 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1683 werror
= cli_spoolss_addform(cli
, mem_ctx
, &handle
, 1, &form
);
1687 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1689 SAFE_FREE(servername
);
1690 SAFE_FREE(printername
);
1695 /****************************************************************************
1696 ****************************************************************************/
1698 static WERROR
cmd_spoolss_setform(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1699 int argc
, const char **argv
)
1703 char *servername
= NULL
, *printername
= NULL
;
1705 BOOL got_handle
= False
;
1707 /* Parse the command arguements */
1710 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1714 /* Get a printer handle */
1716 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1717 strupper_m(servername
);
1718 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1720 werror
= cli_spoolss_open_printer_ex(
1721 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1722 servername
, cli
->user_name
, &handle
);
1724 if (!W_ERROR_IS_OK(werror
))
1729 /* Dummy up some values for the form data */
1731 form
.flags
= FORM_PRINTER
;
1732 form
.size_x
= form
.size_y
= 100;
1738 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1742 werror
= cli_spoolss_setform(cli
, mem_ctx
, &handle
, 1, argv
[2], &form
);
1746 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1748 SAFE_FREE(servername
);
1749 SAFE_FREE(printername
);
1754 /****************************************************************************
1755 ****************************************************************************/
1757 static const char *get_form_flag(int form_flag
)
1759 switch (form_flag
) {
1763 return "FORM_BUILTIN";
1765 return "FORM_PRINTER";
1771 /****************************************************************************
1772 ****************************************************************************/
1774 static void display_form(FORM_1
*form
)
1776 fstring form_name
= "";
1778 if (form
->name
.buffer
)
1779 rpcstr_pull(form_name
, form
->name
.buffer
,
1780 sizeof(form_name
), -1, STR_TERMINATE
);
1783 "\tflag: %s (%d)\n" \
1784 "\twidth: %d, length: %d\n" \
1785 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1786 form_name
, get_form_flag(form
->flag
), form
->flag
,
1787 form
->width
, form
->length
,
1788 form
->left
, form
->right
,
1789 form
->top
, form
->bottom
);
1792 /****************************************************************************
1793 ****************************************************************************/
1795 static WERROR
cmd_spoolss_getform(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1796 int argc
, const char **argv
)
1800 char *servername
= NULL
, *printername
= NULL
;
1802 BOOL got_handle
= False
;
1804 /* Parse the command arguements */
1807 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1811 /* Get a printer handle */
1813 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1814 strupper_m(servername
);
1815 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1817 werror
= cli_spoolss_open_printer_ex(
1818 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1819 servername
, cli
->user_name
, &handle
);
1821 if (!W_ERROR_IS_OK(werror
))
1828 werror
= cli_spoolss_getform(cli
, mem_ctx
, &handle
, argv
[2], 1, &form
);
1830 if (!W_ERROR_IS_OK(werror
))
1833 display_form(&form
);
1837 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1839 SAFE_FREE(servername
);
1840 SAFE_FREE(printername
);
1845 /****************************************************************************
1846 ****************************************************************************/
1848 static WERROR
cmd_spoolss_deleteform(struct cli_state
*cli
,
1849 TALLOC_CTX
*mem_ctx
, int argc
,
1854 char *servername
= NULL
, *printername
= NULL
;
1855 BOOL got_handle
= False
;
1857 /* Parse the command arguements */
1860 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1864 /* Get a printer handle */
1866 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1867 strupper_m(servername
);
1868 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1870 werror
= cli_spoolss_open_printer_ex(
1871 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1872 servername
, cli
->user_name
, &handle
);
1874 if (!W_ERROR_IS_OK(werror
))
1879 /* Delete the form */
1881 werror
= cli_spoolss_deleteform(cli
, mem_ctx
, &handle
, argv
[2]);
1885 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1887 SAFE_FREE(servername
);
1888 SAFE_FREE(printername
);
1893 /****************************************************************************
1894 ****************************************************************************/
1896 static WERROR
cmd_spoolss_enum_forms(struct cli_state
*cli
,
1897 TALLOC_CTX
*mem_ctx
, int argc
,
1902 char *servername
= NULL
, *printername
= NULL
;
1903 BOOL got_handle
= False
;
1904 uint32 needed
, offered
, num_forms
, level
= 1, i
;
1907 /* Parse the command arguements */
1910 printf ("Usage: %s <printer>\n", argv
[0]);
1914 /* Get a printer handle */
1916 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1917 strupper_m(servername
);
1918 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1920 werror
= cli_spoolss_open_printer_ex(
1921 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1922 servername
, cli
->user_name
, &handle
);
1924 if (!W_ERROR_IS_OK(werror
))
1929 /* Enumerate forms */
1931 offered
= needed
= 0;
1932 werror
= cli_spoolss_enumforms(cli
, mem_ctx
, &handle
, level
, &num_forms
, &forms
);
1934 if (!W_ERROR_IS_OK(werror
))
1937 /* Display output */
1939 for (i
= 0; i
< num_forms
; i
++) {
1941 display_form(&forms
[i
]);
1947 cli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1949 SAFE_FREE(servername
);
1950 SAFE_FREE(printername
);
1955 /****************************************************************************
1956 ****************************************************************************/
1958 static WERROR
cmd_spoolss_setprinterdata(struct cli_state
*cli
,
1959 TALLOC_CTX
*mem_ctx
,
1960 int argc
, const char **argv
)
1963 fstring servername
, printername
, user
;
1965 BOOL opened_hnd
= False
;
1966 PRINTER_INFO_CTR ctr
;
1967 PRINTER_INFO_0 info
;
1968 REGISTRY_VALUE value
;
1970 /* parse the command arguements */
1972 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
1973 " <value> <data>\n",
1975 return WERR_INVALID_PARAM
;
1978 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1979 strupper_m(servername
);
1980 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1981 fstrcpy(user
, cli
->user_name
);
1983 value
.type
= REG_NONE
;
1985 if (strequal(argv
[2], "string")) {
1986 value
.type
= REG_SZ
;
1989 if (strequal(argv
[2], "binary")) {
1990 value
.type
= REG_BINARY
;
1993 if (strequal(argv
[2], "dword")) {
1994 value
.type
= REG_DWORD
;
1997 if (strequal(argv
[2], "multistring")) {
1998 value
.type
= REG_MULTI_SZ
;
2001 if (value
.type
== REG_NONE
) {
2002 printf("Unknown data type: %s\n", argv
[2]);
2003 return WERR_INVALID_PARAM
;
2006 /* get a printer handle */
2007 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
2008 MAXIMUM_ALLOWED_ACCESS
, servername
,
2010 if (!W_ERROR_IS_OK(result
))
2015 ctr
.printers_0
= &info
;
2017 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2019 if (!W_ERROR_IS_OK(result
))
2022 printf("%s\n", timestring(True
));
2023 printf("\tchange_id (before set)\t:[0x%x]\n", info
.change_id
);
2025 /* Set the printer data */
2027 fstrcpy(value
.valuename
, argv
[3]);
2029 switch (value
.type
) {
2032 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2033 value
.size
= data
.uni_str_len
* 2;
2034 value
.data_p
= TALLOC_MEMDUP(mem_ctx
, data
.buffer
, value
.size
);
2038 uint32 data
= strtoul(argv
[4], NULL
, 10);
2039 value
.size
= sizeof(data
);
2040 value
.data_p
= TALLOC_MEMDUP(mem_ctx
, &data
, sizeof(data
));
2044 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2045 value
.data_p
= data
.data
;
2046 value
.size
= data
.length
;
2049 case REG_MULTI_SZ
: {
2054 for (i
=4; i
<argc
; i
++) {
2055 if (strcmp(argv
[i
], "NULL") == 0) {
2058 len
+= strlen(argv
[i
])+1;
2062 value
.data_p
= TALLOC_ARRAY(mem_ctx
, char, value
.size
);
2063 if (value
.data_p
== NULL
) {
2064 result
= WERR_NOMEM
;
2070 for (i
=4; i
<argc
; i
++) {
2071 size_t l
= (strlen(argv
[i
])+1)*2;
2072 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2076 SMB_ASSERT(len
== 0);
2080 printf("Unknown data type: %s\n", argv
[2]);
2081 result
= WERR_INVALID_PARAM
;
2085 result
= cli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2087 if (!W_ERROR_IS_OK(result
)) {
2088 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2091 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2093 result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2095 if (!W_ERROR_IS_OK(result
))
2098 printf("%s\n", timestring(True
));
2099 printf("\tchange_id (after set)\t:[0x%x]\n", info
.change_id
);
2104 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
2109 /****************************************************************************
2110 ****************************************************************************/
2112 static void display_job_info_1(JOB_INFO_1
*job
)
2114 fstring username
= "", document
= "", text_status
= "";
2116 rpcstr_pull(username
, job
->username
.buffer
,
2117 sizeof(username
), -1, STR_TERMINATE
);
2119 rpcstr_pull(document
, job
->document
.buffer
,
2120 sizeof(document
), -1, STR_TERMINATE
);
2122 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2123 sizeof(text_status
), -1, STR_TERMINATE
);
2125 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2126 username
, document
, text_status
, job
->pagesprinted
,
2130 /****************************************************************************
2131 ****************************************************************************/
2133 static void display_job_info_2(JOB_INFO_2
*job
)
2135 fstring username
= "", document
= "", text_status
= "";
2137 rpcstr_pull(username
, job
->username
.buffer
,
2138 sizeof(username
), -1, STR_TERMINATE
);
2140 rpcstr_pull(document
, job
->document
.buffer
,
2141 sizeof(document
), -1, STR_TERMINATE
);
2143 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2144 sizeof(text_status
), -1, STR_TERMINATE
);
2146 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job
->position
, job
->jobid
,
2147 username
, document
, text_status
, job
->pagesprinted
,
2148 job
->totalpages
, job
->size
);
2151 /****************************************************************************
2152 ****************************************************************************/
2154 static WERROR
cmd_spoolss_enum_jobs(struct cli_state
*cli
,
2155 TALLOC_CTX
*mem_ctx
, int argc
,
2159 uint32 needed
, offered
, level
= 1, num_jobs
, i
;
2160 BOOL got_hnd
= False
;
2161 pstring printername
;
2162 fstring servername
, user
;
2166 if (argc
< 2 || argc
> 3) {
2167 printf("Usage: %s printername [level]\n", argv
[0]);
2172 level
= atoi(argv
[2]);
2174 /* Open printer handle */
2176 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2177 strupper_m(servername
);
2178 fstrcpy(user
, cli
->user_name
);
2179 slprintf(printername
, sizeof(servername
)-1, "\\\\%s\\", cli
->desthost
);
2180 strupper_m(printername
);
2181 pstrcat(printername
, argv
[1]);
2183 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2184 "", MAXIMUM_ALLOWED_ACCESS
,
2185 servername
, user
, &hnd
);
2187 if (!W_ERROR_IS_OK(result
))
2192 /* Enumerate ports */
2194 offered
= needed
= 0;
2195 result
= cli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2198 if (!W_ERROR_IS_OK(result
))
2201 for (i
= 0; i
< num_jobs
; i
++) {
2204 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2207 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2210 d_printf("unknown info level %d\n", level
);
2217 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2222 /****************************************************************************
2223 ****************************************************************************/
2225 static WERROR
cmd_spoolss_enum_data( struct cli_state
*cli
,
2226 TALLOC_CTX
*mem_ctx
, int argc
,
2230 uint32 i
=0, val_needed
, data_needed
;
2231 BOOL got_hnd
= False
;
2232 pstring printername
;
2233 fstring servername
, user
;
2237 printf("Usage: %s printername\n", argv
[0]);
2241 /* Open printer handle */
2243 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2244 strupper_m(servername
);
2245 fstrcpy(user
, cli
->user_name
);
2246 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->desthost
);
2247 strupper_m(printername
);
2248 pstrcat(printername
, argv
[1]);
2250 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2251 "", MAXIMUM_ALLOWED_ACCESS
,
2252 servername
, user
, &hnd
);
2254 if (!W_ERROR_IS_OK(result
))
2259 /* Enumerate data */
2261 result
= cli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2262 &val_needed
, &data_needed
,
2264 while (W_ERROR_IS_OK(result
)) {
2265 REGISTRY_VALUE value
;
2266 result
= cli_spoolss_enumprinterdata(
2267 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2268 data_needed
, 0, 0, &value
);
2269 if (W_ERROR_IS_OK(result
))
2270 display_reg_value(value
);
2272 if (W_ERROR_V(result
) == ERRnomoreitems
)
2273 result
= W_ERROR(ERRsuccess
);
2277 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2282 /****************************************************************************
2283 ****************************************************************************/
2285 static WERROR
cmd_spoolss_enum_data_ex( struct cli_state
*cli
,
2286 TALLOC_CTX
*mem_ctx
, int argc
,
2291 BOOL got_hnd
= False
;
2292 pstring printername
;
2293 fstring servername
, user
;
2294 const char *keyname
= NULL
;
2296 REGVAL_CTR
*ctr
= NULL
;
2299 printf("Usage: %s printername <keyname>\n", argv
[0]);
2305 /* Open printer handle */
2307 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2308 strupper_m(servername
);
2309 fstrcpy(user
, cli
->user_name
);
2310 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->desthost
);
2311 strupper_m(printername
);
2312 pstrcat(printername
, argv
[1]);
2314 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2315 "", MAXIMUM_ALLOWED_ACCESS
,
2316 servername
, user
, &hnd
);
2318 if (!W_ERROR_IS_OK(result
))
2323 /* Enumerate subkeys */
2325 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2328 result
= cli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2330 if (!W_ERROR_IS_OK(result
))
2333 for (i
=0; i
< ctr
->num_values
; i
++) {
2334 display_reg_value(*(ctr
->values
[i
]));
2341 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2346 /****************************************************************************
2347 ****************************************************************************/
2349 static WERROR
cmd_spoolss_enum_printerkey( struct cli_state
*cli
,
2350 TALLOC_CTX
*mem_ctx
, int argc
,
2354 BOOL got_hnd
= False
;
2355 pstring printername
;
2356 fstring servername
, user
;
2357 const char *keyname
= NULL
;
2359 uint16
*keylist
= NULL
, *curkey
;
2361 if (argc
< 2 || argc
> 3) {
2362 printf("Usage: %s printername [keyname]\n", argv
[0]);
2371 /* Open printer handle */
2373 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2374 strupper_m(servername
);
2375 fstrcpy(user
, cli
->user_name
);
2376 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->desthost
);
2377 strupper_m(printername
);
2378 pstrcat(printername
, argv
[1]);
2380 result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2381 "", MAXIMUM_ALLOWED_ACCESS
,
2382 servername
, user
, &hnd
);
2384 if (!W_ERROR_IS_OK(result
))
2389 /* Enumerate subkeys */
2391 result
= cli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2393 if (!W_ERROR_IS_OK(result
))
2397 while (*curkey
!= 0) {
2399 rpcstr_pull(subkey
, curkey
, sizeof(subkey
), -1,
2401 printf("%s\n", subkey
);
2402 curkey
+= strlen(subkey
) + 1;
2409 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2414 /****************************************************************************
2415 ****************************************************************************/
2417 static WERROR
cmd_spoolss_rffpcnex(struct cli_state
*cli
,
2418 TALLOC_CTX
*mem_ctx
, int argc
,
2421 fstring servername
, printername
;
2423 BOOL got_hnd
= False
;
2425 SPOOL_NOTIFY_OPTION option
;
2428 printf("Usage: %s printername\n", argv
[0]);
2435 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", cli
->desthost
);
2436 strupper_m(servername
);
2438 slprintf(printername
, sizeof(printername
) - 1, "\\\\%s\\%s", cli
->desthost
,
2440 strupper_m(printername
);
2442 result
= cli_spoolss_open_printer_ex(
2443 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
2444 servername
, cli
->user_name
, &hnd
);
2446 if (!W_ERROR_IS_OK(result
)) {
2447 printf("Error opening %s\n", argv
[1]);
2453 /* Create spool options */
2455 ZERO_STRUCT(option
);
2458 option
.option_type_ptr
= 1;
2459 option
.count
= option
.ctr
.count
= 2;
2461 option
.ctr
.type
= TALLOC_ARRAY(mem_ctx
, SPOOL_NOTIFY_OPTION_TYPE
, 2);
2463 ZERO_STRUCT(option
.ctr
.type
[0]);
2464 option
.ctr
.type
[0].type
= PRINTER_NOTIFY_TYPE
;
2465 option
.ctr
.type
[0].count
= option
.ctr
.type
[0].count2
= 1;
2466 option
.ctr
.type
[0].fields_ptr
= 1;
2467 option
.ctr
.type
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2469 ZERO_STRUCT(option
.ctr
.type
[1]);
2470 option
.ctr
.type
[1].type
= JOB_NOTIFY_TYPE
;
2471 option
.ctr
.type
[1].count
= option
.ctr
.type
[1].count2
= 1;
2472 option
.ctr
.type
[1].fields_ptr
= 1;
2473 option
.ctr
.type
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2477 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", myhostname());
2478 strupper_m(servername
);
2480 result
= cli_spoolss_rffpcnex(
2481 cli
, mem_ctx
, &hnd
, 0, 0, servername
, 123, &option
);
2483 if (!W_ERROR_IS_OK(result
)) {
2484 printf("Error rffpcnex %s\n", argv
[1]);
2490 cli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2495 /****************************************************************************
2496 ****************************************************************************/
2498 static BOOL
compare_printer( struct cli_state
*cli1
, POLICY_HND
*hnd1
,
2499 struct cli_state
*cli2
, POLICY_HND
*hnd2
)
2501 PRINTER_INFO_CTR ctr1
, ctr2
;
2503 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2505 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
2506 werror
= cli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 2, &ctr1
);
2507 if ( !W_ERROR_IS_OK(werror
) ) {
2508 printf("failed (%s)\n", dos_errstr(werror
));
2509 talloc_destroy(mem_ctx
);
2514 printf("Retrieving printer properties for %s...", cli2
->desthost
);
2515 werror
= cli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 2, &ctr2
);
2516 if ( !W_ERROR_IS_OK(werror
) ) {
2517 printf("failed (%s)\n", dos_errstr(werror
));
2518 talloc_destroy(mem_ctx
);
2524 talloc_destroy(mem_ctx
);
2529 /****************************************************************************
2530 ****************************************************************************/
2532 static BOOL
compare_printer_secdesc( struct cli_state
*cli1
, POLICY_HND
*hnd1
,
2533 struct cli_state
*cli2
, POLICY_HND
*hnd2
)
2535 PRINTER_INFO_CTR ctr1
, ctr2
;
2537 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2538 SEC_DESC
*sd1
, *sd2
;
2542 printf("Retreiving printer security for %s...", cli1
->desthost
);
2543 werror
= cli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 3, &ctr1
);
2544 if ( !W_ERROR_IS_OK(werror
) ) {
2545 printf("failed (%s)\n", dos_errstr(werror
));
2551 printf("Retrieving printer security for %s...", cli2
->desthost
);
2552 werror
= cli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 3, &ctr2
);
2553 if ( !W_ERROR_IS_OK(werror
) ) {
2554 printf("failed (%s)\n", dos_errstr(werror
));
2563 if ( (ctr1
.printers_3
!= ctr2
.printers_3
) && (!ctr1
.printers_3
|| !ctr2
.printers_3
) ) {
2564 printf("NULL PRINTER_INFO_3!\n");
2569 sd1
= ctr1
.printers_3
->secdesc
;
2570 sd2
= ctr2
.printers_3
->secdesc
;
2572 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2573 printf("NULL secdesc!\n");
2578 if ( (ctr1
.printers_3
->flags
!= ctr1
.printers_3
->flags
) || !sec_desc_equal( sd1
, sd2
) ) {
2579 printf("Security Descriptors *not* equal!\n");
2584 printf("Security descriptors match\n");
2587 talloc_destroy(mem_ctx
);
2592 /****************************************************************************
2593 ****************************************************************************/
2595 static WERROR
cmd_spoolss_printercmp(struct cli_state
*cli
,
2596 TALLOC_CTX
*mem_ctx
, int argc
,
2599 fstring printername
, servername1
, servername2
;
2600 pstring printername_path
;
2601 struct cli_state
*cli_server1
= cli
;
2602 struct cli_state
*cli_server2
= NULL
;
2603 POLICY_HND hPrinter1
, hPrinter2
;
2608 printf("Usage: %s <printer> <server>\n", argv
[0]);
2612 fstrcpy( printername
, argv
[1] );
2614 fstr_sprintf( servername1
, cli
->desthost
);
2615 fstrcpy( servername2
, argv
[2] );
2616 strupper_m( servername1
);
2617 strupper_m( servername2
);
2620 /* first get the connection to the remote server */
2622 nt_status
= cli_full_connection(&cli_server2
, global_myname(), servername2
,
2625 cmdline_auth_info
.username
,
2627 cmdline_auth_info
.password
,
2628 cmdline_auth_info
.use_kerberos
? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2629 cmdline_auth_info
.signing_state
, NULL
);
2631 if ( !NT_STATUS_IS_OK(nt_status
) )
2632 return WERR_GENERAL_FAILURE
;
2634 if ( !cli_nt_session_open(cli_server2
, PI_SPOOLSS
) )
2635 return WERR_GENERAL_FAILURE
;
2637 /* now open up both printers */
2639 pstr_sprintf( printername_path
, "\\\\%s\\%s", servername1
, printername
);
2640 printf("Opening %s...", printername_path
);
2641 werror
= cli_spoolss_open_printer_ex( cli_server1
, mem_ctx
, printername_path
,
2642 "", PRINTER_ALL_ACCESS
, servername1
, cli_server1
->user_name
, &hPrinter1
);
2643 if ( !W_ERROR_IS_OK(werror
) ) {
2644 printf("failed (%s)\n", dos_errstr(werror
));
2649 pstr_sprintf( printername_path
, "\\\\%s\\%s", servername2
, printername
);
2650 printf("Opening %s...", printername_path
);
2651 werror
= cli_spoolss_open_printer_ex( cli_server2
, mem_ctx
, printername_path
,
2652 "", PRINTER_ALL_ACCESS
, servername2
, cli_server2
->user_name
, &hPrinter2
);
2653 if ( !W_ERROR_IS_OK(werror
) ) {
2654 printf("failed (%s)\n", dos_errstr(werror
));
2660 compare_printer( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2661 compare_printer_secdesc( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2663 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2670 printf("Closing printers...");
2671 cli_spoolss_close_printer( cli_server1
, mem_ctx
, &hPrinter1
);
2672 cli_spoolss_close_printer( cli_server2
, mem_ctx
, &hPrinter2
);
2675 /* close the second remote connection */
2677 cli_shutdown( cli_server2
);
2682 /* List of commands exported by this module */
2683 struct cmd_set spoolss_commands
[] = {
2687 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, PI_SPOOLSS
, "Add a print driver", "" },
2688 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, PI_SPOOLSS
, "Add a printer", "" },
2689 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, PI_SPOOLSS
, "Delete a printer driver", "" },
2690 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, PI_SPOOLSS
, "Delete a printer driver with files", "" },
2691 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, PI_SPOOLSS
, "Enumerate printer data", "" },
2692 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, PI_SPOOLSS
, "Enumerate printer data for a key", "" },
2693 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, PI_SPOOLSS
, "Enumerate printer keys", "" },
2694 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, PI_SPOOLSS
, "Enumerate print jobs", "" },
2695 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, PI_SPOOLSS
, "Enumerate printer ports", "" },
2696 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, PI_SPOOLSS
, "Enumerate installed printer drivers", "" },
2697 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, PI_SPOOLSS
, "Enumerate printers", "" },
2698 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, PI_SPOOLSS
, "Get print driver data", "" },
2699 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, PI_SPOOLSS
, "Get printer driver data with keyname", ""},
2700 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, PI_SPOOLSS
, "Get print driver information", "" },
2701 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, PI_SPOOLSS
, "Get print driver upload directory", "" },
2702 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, PI_SPOOLSS
, "Get printer info", "" },
2703 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, PI_SPOOLSS
, "Open printer handle", "" },
2704 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, PI_SPOOLSS
, "Set printer driver", "" },
2705 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, PI_SPOOLSS
, "Get print processor directory", "" },
2706 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, PI_SPOOLSS
, "Add form", "" },
2707 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, PI_SPOOLSS
, "Set form", "" },
2708 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, PI_SPOOLSS
, "Get form", "" },
2709 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, PI_SPOOLSS
, "Delete form", "" },
2710 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, PI_SPOOLSS
, "Enumerate forms", "" },
2711 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, PI_SPOOLSS
, "Set printer comment", "" },
2712 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, PI_SPOOLSS
, "Set printername", "" },
2713 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, PI_SPOOLSS
, "Set REG_SZ printer data", "" },
2714 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, PI_SPOOLSS
, "Rffpcnex test", "" },
2715 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, PI_SPOOLSS
, "Printer comparison test", "" },