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 3 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, see <http://www.gnu.org/licenses/>.
25 #include "rpcclient.h"
27 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
29 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
30 _cli->srv_name_slash, _arg); \
31 W_ERROR_HAVE_NO_MEMORY(_printername); \
35 const char *long_archi
;
36 const char *short_archi
;
40 /* The version int is used by getdrivers. Note that
41 all architecture strings that support mutliple
42 versions must be grouped together since enumdrivers
43 uses this property to prevent issuing multiple
44 enumdriver calls for the same arch */
47 static const struct table_node archi_table
[]= {
49 {"Windows 4.0", "WIN40", 0 },
50 {"Windows NT x86", "W32X86", 2 },
51 {"Windows NT x86", "W32X86", 3 },
52 {"Windows NT R4000", "W32MIPS", 2 },
53 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
54 {"Windows NT PowerPC", "W32PPC", 2 },
55 {"Windows IA64", "IA64", 3 },
56 {"Windows x64", "x64", 3 },
63 * rpcclient module for SPOOLSS rpc pipe.
65 * This generally just parses and checks command lines, and then calls
66 * a cli_spoolss function.
69 /****************************************************************************
70 function to do the mapping between the long architecture name and
72 ****************************************************************************/
74 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
78 DEBUG(107,("Getting architecture dependant directory\n"));
81 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
82 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
84 if (archi_table
[i
].long_archi
==NULL
) {
85 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
89 /* this might be client code - but shouldn't this be an fstrcpy etc? */
92 DEBUGADD(108,("index: [%d]\n", i
));
93 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
94 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
96 return archi_table
[i
].short_archi
;
99 /****************************************************************************
100 ****************************************************************************/
102 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
104 int argc
, const char **argv
)
110 printf("Usage: %s <printername>\n", argv
[0]);
115 return WERR_GENERAL_FAILURE
;
117 /* Open the printer handle */
119 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
123 if (W_ERROR_IS_OK(werror
)) {
124 printf("Printer %s opened successfully\n", argv
[1]);
125 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, &werror
);
127 if (!W_ERROR_IS_OK(werror
)) {
128 printf("Error closing printer handle! (%s)\n",
129 get_dos_error_msg(werror
));
137 /****************************************************************************
138 ****************************************************************************/
140 static void display_print_info_0(PRINTER_INFO_0
*i0
)
143 fstring servername
= "";
148 rpcstr_pull(name
, i0
->printername
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
150 rpcstr_pull(servername
, i0
->servername
.buffer
, sizeof(servername
), -1,STR_TERMINATE
);
152 printf("\tprintername:[%s]\n", name
);
153 printf("\tservername:[%s]\n", servername
);
154 printf("\tcjobs:[0x%x]\n", i0
->cjobs
);
155 printf("\ttotal_jobs:[0x%x]\n", i0
->total_jobs
);
157 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0
->year
, i0
->month
,
158 i0
->day
, i0
->dayofweek
);
159 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0
->hour
, i0
->minute
,
160 i0
->second
, i0
->milliseconds
);
162 printf("\tglobal_counter:[0x%x]\n", i0
->global_counter
);
163 printf("\ttotal_pages:[0x%x]\n", i0
->total_pages
);
165 printf("\tmajorversion:[0x%x]\n", i0
->major_version
);
166 printf("\tbuildversion:[0x%x]\n", i0
->build_version
);
168 printf("\tunknown7:[0x%x]\n", i0
->unknown7
);
169 printf("\tunknown8:[0x%x]\n", i0
->unknown8
);
170 printf("\tunknown9:[0x%x]\n", i0
->unknown9
);
171 printf("\tsession_counter:[0x%x]\n", i0
->session_counter
);
172 printf("\tunknown11:[0x%x]\n", i0
->unknown11
);
173 printf("\tprinter_errors:[0x%x]\n", i0
->printer_errors
);
174 printf("\tunknown13:[0x%x]\n", i0
->unknown13
);
175 printf("\tunknown14:[0x%x]\n", i0
->unknown14
);
176 printf("\tunknown15:[0x%x]\n", i0
->unknown15
);
177 printf("\tunknown16:[0x%x]\n", i0
->unknown16
);
178 printf("\tchange_id:[0x%x]\n", i0
->change_id
);
179 printf("\tunknown18:[0x%x]\n", i0
->unknown18
);
180 printf("\tstatus:[0x%x]\n", i0
->status
);
181 printf("\tunknown20:[0x%x]\n", i0
->unknown20
);
182 printf("\tc_setprinter:[0x%x]\n", i0
->c_setprinter
);
183 printf("\tunknown22:[0x%x]\n", i0
->unknown22
);
184 printf("\tunknown23:[0x%x]\n", i0
->unknown23
);
185 printf("\tunknown24:[0x%x]\n", i0
->unknown24
);
186 printf("\tunknown25:[0x%x]\n", i0
->unknown25
);
187 printf("\tunknown26:[0x%x]\n", i0
->unknown26
);
188 printf("\tunknown27:[0x%x]\n", i0
->unknown27
);
189 printf("\tunknown28:[0x%x]\n", i0
->unknown28
);
190 printf("\tunknown29:[0x%x]\n", i0
->unknown29
);
195 /****************************************************************************
196 ****************************************************************************/
198 static void display_print_info_1(PRINTER_INFO_1
*i1
)
204 rpcstr_pull(desc
, i1
->description
.buffer
, sizeof(desc
), -1,
207 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
208 rpcstr_pull(comm
, i1
->comment
.buffer
, sizeof(comm
), -1, STR_TERMINATE
);
210 printf("\tflags:[0x%x]\n", i1
->flags
);
211 printf("\tname:[%s]\n", name
);
212 printf("\tdescription:[%s]\n", desc
);
213 printf("\tcomment:[%s]\n", comm
);
218 /****************************************************************************
219 ****************************************************************************/
221 static void display_print_info_2(PRINTER_INFO_2
*i2
)
223 fstring servername
= "";
224 fstring printername
= "";
225 fstring sharename
= "";
226 fstring portname
= "";
227 fstring drivername
= "";
228 fstring comment
= "";
229 fstring location
= "";
230 fstring sepfile
= "";
231 fstring printprocessor
= "";
232 fstring datatype
= "";
233 fstring parameters
= "";
235 rpcstr_pull(servername
, i2
->servername
.buffer
,sizeof(servername
), -1, STR_TERMINATE
);
236 rpcstr_pull(printername
, i2
->printername
.buffer
,sizeof(printername
), -1, STR_TERMINATE
);
237 rpcstr_pull(sharename
, i2
->sharename
.buffer
,sizeof(sharename
), -1, STR_TERMINATE
);
238 rpcstr_pull(portname
, i2
->portname
.buffer
,sizeof(portname
), -1, STR_TERMINATE
);
239 rpcstr_pull(drivername
, i2
->drivername
.buffer
,sizeof(drivername
), -1, STR_TERMINATE
);
240 rpcstr_pull(comment
, i2
->comment
.buffer
,sizeof(comment
), -1, STR_TERMINATE
);
241 rpcstr_pull(location
, i2
->location
.buffer
,sizeof(location
), -1, STR_TERMINATE
);
242 rpcstr_pull(sepfile
, i2
->sepfile
.buffer
,sizeof(sepfile
), -1, STR_TERMINATE
);
243 rpcstr_pull(printprocessor
, i2
->printprocessor
.buffer
,sizeof(printprocessor
), -1, STR_TERMINATE
);
244 rpcstr_pull(datatype
, i2
->datatype
.buffer
,sizeof(datatype
), -1, STR_TERMINATE
);
245 rpcstr_pull(parameters
, i2
->parameters
.buffer
,sizeof(parameters
), -1, STR_TERMINATE
);
247 printf("\tservername:[%s]\n", servername
);
248 printf("\tprintername:[%s]\n", printername
);
249 printf("\tsharename:[%s]\n", sharename
);
250 printf("\tportname:[%s]\n", portname
);
251 printf("\tdrivername:[%s]\n", drivername
);
252 printf("\tcomment:[%s]\n", comment
);
253 printf("\tlocation:[%s]\n", location
);
254 printf("\tsepfile:[%s]\n", sepfile
);
255 printf("\tprintprocessor:[%s]\n", printprocessor
);
256 printf("\tdatatype:[%s]\n", datatype
);
257 printf("\tparameters:[%s]\n", parameters
);
258 printf("\tattributes:[0x%x]\n", i2
->attributes
);
259 printf("\tpriority:[0x%x]\n", i2
->priority
);
260 printf("\tdefaultpriority:[0x%x]\n", i2
->defaultpriority
);
261 printf("\tstarttime:[0x%x]\n", i2
->starttime
);
262 printf("\tuntiltime:[0x%x]\n", i2
->untiltime
);
263 printf("\tstatus:[0x%x]\n", i2
->status
);
264 printf("\tcjobs:[0x%x]\n", i2
->cjobs
);
265 printf("\taverageppm:[0x%x]\n", i2
->averageppm
);
268 display_sec_desc(i2
->secdesc
);
273 /****************************************************************************
274 ****************************************************************************/
276 static void display_print_info_3(PRINTER_INFO_3
*i3
)
278 display_sec_desc(i3
->secdesc
);
283 /****************************************************************************
284 ****************************************************************************/
286 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
288 printf("\tguid:[%s]\n", r
->guid
);
289 printf("\taction:[0x%x]\n", r
->action
);
293 /****************************************************************************
294 ****************************************************************************/
296 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
298 int argc
, const char **argv
)
301 uint32 info_level
= 1;
302 PRINTER_INFO_CTR ctr
;
303 uint32 i
= 0, num_printers
;
308 printf("Usage: %s [level] [name]\n", argv
[0]);
313 info_level
= atoi(argv
[1]);
316 fstrcpy(name
, argv
[2]);
318 slprintf(name
, sizeof(name
)-1, "\\\\%s", cli
->desthost
);
324 result
= rpccli_spoolss_enum_printers(cli
, mem_ctx
, name
, PRINTER_ENUM_LOCAL
,
325 info_level
, &num_printers
, &ctr
);
327 if (W_ERROR_IS_OK(result
)) {
330 printf ("No printers returned.\n");
334 for (i
= 0; i
< num_printers
; i
++) {
337 display_print_info_0(&ctr
.printers_0
[i
]);
340 display_print_info_1(&ctr
.printers_1
[i
]);
343 display_print_info_2(&ctr
.printers_2
[i
]);
346 display_print_info_3(&ctr
.printers_3
[i
]);
349 printf("unknown info level %d\n", info_level
);
359 /****************************************************************************
360 ****************************************************************************/
362 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
364 printf("\tPort Name:\t[%s]\n", r
->port_name
);
367 /****************************************************************************
368 ****************************************************************************/
370 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
372 printf("\tPort Name:\t[%s]\n", r
->port_name
);
373 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
374 printf("\tDescription:\t[%s]\n", r
->description
);
375 printf("\tPort Type:\t" );
377 int comma
= 0; /* hack */
379 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
383 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
384 printf( "%sWrite", comma
? ", " : "" );
387 /* These two have slightly different interpretations
388 on 95/98/ME but I'm disregarding that for now */
389 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
390 printf( "%sRedirected", comma
? ", " : "" );
393 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
394 printf( "%sNet-Attached", comma
? ", " : "" );
398 printf( "[Unset]\n" );
400 printf("\tReserved:\t[%d]\n", r
->reserved
);
404 /****************************************************************************
405 ****************************************************************************/
407 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
408 TALLOC_CTX
*mem_ctx
, int argc
,
412 uint32 info_level
= 1;
414 union spoolss_PortInfo
*info
;
417 printf("Usage: %s [level]\n", argv
[0]);
422 info_level
= atoi(argv
[1]);
424 /* Enumerate ports */
426 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
432 if (W_ERROR_IS_OK(result
)) {
435 for (i
= 0; i
< returned
; i
++) {
436 switch (info_level
) {
438 display_port_info_1(&info
[i
].info1
);
441 display_port_info_2(&info
[i
].info2
);
444 printf("unknown info level %d\n", info_level
);
453 /****************************************************************************
454 ****************************************************************************/
456 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
458 int argc
, const char **argv
)
463 uint32 info_level
= 2;
464 union spoolss_PrinterInfo info
;
465 struct spoolss_SetPrinterInfoCtr info_ctr
;
466 const char *printername
, *comment
= NULL
;
467 struct spoolss_DevmodeContainer devmode_ctr
;
468 struct sec_desc_buf secdesc_ctr
;
470 if (argc
== 1 || argc
> 3) {
471 printf("Usage: %s printername comment\n", argv
[0]);
476 /* Open a printer handle */
481 ZERO_STRUCT(devmode_ctr
);
482 ZERO_STRUCT(secdesc_ctr
);
484 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
486 /* get a printer handle */
487 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
491 if (!W_ERROR_IS_OK(result
))
494 /* Get printer info */
495 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
500 if (!W_ERROR_IS_OK(result
))
504 /* Modify the comment. */
505 info
.info2
.comment
= comment
;
506 info
.info2
.secdesc
= NULL
;
507 info
.info2
.devmode
= NULL
;
510 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
512 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
519 if (W_ERROR_IS_OK(result
))
520 printf("Success in setting comment.\n");
523 if (is_valid_policy_hnd(&pol
))
524 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
529 /****************************************************************************
530 ****************************************************************************/
532 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
534 int argc
, const char **argv
)
539 uint32 info_level
= 2;
540 union spoolss_PrinterInfo info
;
541 const char *printername
,
542 *new_printername
= NULL
;
543 struct spoolss_SetPrinterInfoCtr info_ctr
;
544 struct spoolss_DevmodeContainer devmode_ctr
;
545 struct sec_desc_buf secdesc_ctr
;
547 ZERO_STRUCT(devmode_ctr
);
548 ZERO_STRUCT(secdesc_ctr
);
550 if (argc
== 1 || argc
> 3) {
551 printf("Usage: %s printername new_printername\n", argv
[0]);
556 /* Open a printer handle */
558 new_printername
= argv
[2];
561 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
563 /* get a printer handle */
564 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
568 if (!W_ERROR_IS_OK(result
))
571 /* Get printer info */
572 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
577 if (!W_ERROR_IS_OK(result
))
580 /* Modify the printername. */
581 info
.info2
.printername
= new_printername
;
582 info
.info2
.devmode
= NULL
;
583 info
.info2
.secdesc
= NULL
;
585 info_ctr
.level
= info_level
;
586 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
588 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
595 if (W_ERROR_IS_OK(result
))
596 printf("Success in setting printername.\n");
599 if (is_valid_policy_hnd(&pol
))
600 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
605 /****************************************************************************
606 ****************************************************************************/
608 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
610 int argc
, const char **argv
)
614 uint32 info_level
= 1;
615 const char *printername
;
616 union spoolss_PrinterInfo info
;
618 if (argc
== 1 || argc
> 3) {
619 printf("Usage: %s <printername> [level]\n", argv
[0]);
623 /* Open a printer handle */
625 info_level
= atoi(argv
[2]);
628 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
630 /* get a printer handle */
632 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
634 SEC_FLAG_MAXIMUM_ALLOWED
,
636 if (!W_ERROR_IS_OK(result
))
639 /* Get printer info */
641 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
646 if (!W_ERROR_IS_OK(result
))
649 /* Display printer info */
650 switch (info_level
) {
653 display_print_info_0(ctr
.printers_0
);
656 display_print_info_1(ctr
.printers_1
);
659 display_print_info_2(ctr
.printers_2
);
662 display_print_info_3(ctr
.printers_3
);
666 display_print_info7(&info
.info7
);
669 printf("unknown info level %d\n", info_level
);
673 if (is_valid_policy_hnd(&pol
))
674 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
679 /****************************************************************************
680 ****************************************************************************/
682 static void display_reg_value(REGISTRY_VALUE value
)
688 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
689 *((uint32
*) value
.data_p
));
692 rpcstr_pull_talloc(talloc_tos(),
697 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
700 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
702 printf("%s: REG_BINARY:", value
.valuename
);
704 for (i
=0; i
<len
; i
++) {
705 if (hex
[i
] == '\0') {
718 uint32 i
, num_values
;
721 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL
, value
.data_p
,
722 value
.size
, &num_values
,
724 d_printf("reg_pull_multi_sz failed\n");
728 for (i
=0; i
<num_values
; i
++) {
729 d_printf("%s\n", values
[i
]);
735 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
740 /****************************************************************************
741 ****************************************************************************/
743 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
745 int argc
, const char **argv
)
750 const char *valuename
;
751 REGISTRY_VALUE value
;
754 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
755 printf("<printername> of . queries print server\n");
760 /* Open a printer handle */
762 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
763 fstrcpy(printername
, cli
->srv_name_slash
);
765 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
766 cli
->srv_name_slash
, argv
[1]);
768 /* get a printer handle */
770 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
772 SEC_FLAG_MAXIMUM_ALLOWED
,
774 if (!W_ERROR_IS_OK(result
))
777 /* Get printer info */
779 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
781 if (!W_ERROR_IS_OK(result
))
784 /* Display printer data */
786 fstrcpy(value
.valuename
, valuename
);
787 display_reg_value(value
);
791 if (is_valid_policy_hnd(&pol
))
792 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
797 /****************************************************************************
798 ****************************************************************************/
800 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
802 int argc
, const char **argv
)
808 const char *valuename
, *keyname
;
809 REGISTRY_VALUE value
;
812 uint8_t *buffer
= NULL
;
813 uint32_t offered
= 0;
817 printf("Usage: %s <printername> <keyname> <valuename>\n",
819 printf("<printername> of . queries print server\n");
825 /* Open a printer handle */
827 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
828 fstrcpy(printername
, cli
->srv_name_slash
);
830 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
831 cli
->srv_name_slash
, argv
[1]);
833 /* get a printer handle */
835 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
837 SEC_FLAG_MAXIMUM_ALLOWED
,
839 if (!W_ERROR_IS_OK(result
))
842 /* Get printer info */
844 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
853 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
855 buffer
= talloc_array(mem_ctx
, uint8_t, needed
);
856 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
867 if (!NT_STATUS_IS_OK(status
)) {
871 if (!W_ERROR_IS_OK(result
)) {
876 if (!W_ERROR_IS_OK(result
))
879 /* Display printer data */
881 fstrcpy(value
.valuename
, valuename
);
884 value
.data_p
= buffer
;
886 display_reg_value(value
);
889 if (is_valid_policy_hnd(&pol
))
890 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
895 /****************************************************************************
896 ****************************************************************************/
898 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
904 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
906 printf ("Printer Driver Info 1:\n");
907 printf ("\tDriver Name: [%s]\n\n", name
);
912 /****************************************************************************
913 ****************************************************************************/
915 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
918 fstring architecture
;
925 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
926 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
927 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
928 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
929 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
931 printf ("Printer Driver Info 2:\n");
932 printf ("\tVersion: [%x]\n", i1
->version
);
933 printf ("\tDriver Name: [%s]\n", name
);
934 printf ("\tArchitecture: [%s]\n", architecture
);
935 printf ("\tDriver Path: [%s]\n", driverpath
);
936 printf ("\tDatafile: [%s]\n", datafile
);
937 printf ("\tConfigfile: [%s]\n\n", configfile
);
942 /****************************************************************************
943 ****************************************************************************/
945 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
948 fstring architecture
= "";
949 fstring driverpath
= "";
950 fstring datafile
= "";
951 fstring configfile
= "";
952 fstring helpfile
= "";
953 fstring dependentfiles
= "";
954 fstring monitorname
= "";
955 fstring defaultdatatype
= "";
963 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
964 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
965 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
966 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
967 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
968 rpcstr_pull(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
), -1, STR_TERMINATE
);
969 rpcstr_pull(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
), -1, STR_TERMINATE
);
970 rpcstr_pull(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
), -1, STR_TERMINATE
);
972 printf ("Printer Driver Info 3:\n");
973 printf ("\tVersion: [%x]\n", i1
->version
);
974 printf ("\tDriver Name: [%s]\n",name
);
975 printf ("\tArchitecture: [%s]\n", architecture
);
976 printf ("\tDriver Path: [%s]\n", driverpath
);
977 printf ("\tDatafile: [%s]\n", datafile
);
978 printf ("\tConfigfile: [%s]\n", configfile
);
979 printf ("\tHelpfile: [%s]\n\n", helpfile
);
983 rpcstr_pull(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
), -1, STR_TERMINATE
);
985 length
+=strlen(dependentfiles
)+1;
987 if (strlen(dependentfiles
) > 0)
989 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
999 printf ("\tMonitorname: [%s]\n", monitorname
);
1000 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
1005 /****************************************************************************
1006 ****************************************************************************/
1008 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1014 printf("Printer Driver Info 1:\n");
1015 printf("\tDriver Name: [%s]\n\n", r
->driver_name
);
1018 /****************************************************************************
1019 ****************************************************************************/
1021 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1027 printf("Printer Driver Info 2:\n");
1028 printf("\tVersion: [%x]\n", r
->version
);
1029 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1030 printf("\tArchitecture: [%s]\n", r
->architecture
);
1031 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1032 printf("\tDatafile: [%s]\n", r
->data_file
);
1033 printf("\tConfigfile: [%s]\n\n", r
->config_file
);
1036 /****************************************************************************
1037 ****************************************************************************/
1039 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1047 printf("Printer Driver Info 3:\n");
1048 printf("\tVersion: [%x]\n", r
->version
);
1049 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1050 printf("\tArchitecture: [%s]\n", r
->architecture
);
1051 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1052 printf("\tDatafile: [%s]\n", r
->data_file
);
1053 printf("\tConfigfile: [%s]\n\n", r
->config_file
);
1054 printf("\tHelpfile: [%s]\n\n", r
->help_file
);
1056 for (i
=0; r
->dependent_files
[i
] != NULL
; i
++) {
1057 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1062 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1063 printf("\tDefaultdatatype: [%s]\n\n", r
->default_datatype
);
1067 /****************************************************************************
1068 ****************************************************************************/
1070 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1071 TALLOC_CTX
*mem_ctx
,
1072 int argc
, const char **argv
)
1076 uint32 info_level
= 3;
1077 const char *printername
;
1079 bool success
= False
;
1080 union spoolss_DriverInfo info
;
1081 uint32_t server_major_version
;
1082 uint32_t server_minor_version
;
1084 if ((argc
== 1) || (argc
> 3))
1086 printf("Usage: %s <printername> [level]\n", argv
[0]);
1090 /* get the arguments need to open the printer handle */
1092 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1095 info_level
= atoi(argv
[2]);
1097 /* Open a printer handle */
1099 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1103 if (!W_ERROR_IS_OK(werror
)) {
1104 printf("Error opening printer handle for %s!\n", printername
);
1108 /* loop through and print driver info level for each architecture */
1110 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1112 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1114 archi_table
[i
].long_archi
,
1117 archi_table
[i
].version
,
1120 &server_major_version
,
1121 &server_minor_version
);
1122 if (!W_ERROR_IS_OK(werror
))
1125 /* need at least one success */
1129 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1131 switch (info_level
) {
1133 display_print_driver1(&info
.info1
);
1136 display_print_driver2(&info
.info2
);
1139 display_print_driver3(&info
.info3
);
1142 printf("unknown info level %d\n", info_level
);
1149 if (is_valid_policy_hnd(&pol
))
1150 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1158 /****************************************************************************
1159 ****************************************************************************/
1161 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1162 TALLOC_CTX
*mem_ctx
,
1163 int argc
, const char **argv
)
1165 WERROR werror
= WERR_OK
;
1166 uint32 info_level
= 1;
1167 PRINTER_DRIVER_CTR ctr
;
1172 printf("Usage: enumdrivers [level]\n");
1177 info_level
= atoi(argv
[1]);
1180 /* loop through and print driver info level for each architecture */
1181 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1182 /* check to see if we already asked for this architecture string */
1184 if ( i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
) )
1187 werror
= rpccli_spoolss_enumprinterdrivers(
1188 cli
, mem_ctx
, info_level
,
1189 archi_table
[i
].long_archi
, &returned
, &ctr
);
1191 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1192 printf ("Server does not support environment [%s]\n",
1193 archi_table
[i
].long_archi
);
1201 if (!W_ERROR_IS_OK(werror
)) {
1202 printf ("Error getting driver for environment [%s] - %d\n",
1203 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1207 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1212 for (j
=0; j
< returned
; j
++) {
1213 display_print_driver_1 (&ctr
.info1
[j
]);
1217 for (j
=0; j
< returned
; j
++) {
1218 display_print_driver_2 (&ctr
.info2
[j
]);
1222 for (j
=0; j
< returned
; j
++) {
1223 display_print_driver_3 (&ctr
.info3
[j
]);
1227 printf("unknown info level %d\n", info_level
);
1228 return WERR_UNKNOWN_LEVEL
;
1235 /****************************************************************************
1236 ****************************************************************************/
1238 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1240 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1243 /****************************************************************************
1244 ****************************************************************************/
1246 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1247 TALLOC_CTX
*mem_ctx
,
1248 int argc
, const char **argv
)
1252 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1255 union spoolss_DriverDirectoryInfo info
;
1259 printf("Usage: %s [environment]\n", argv
[0]);
1263 /* Get the arguments need to open the printer handle */
1269 /* Get the directory. Only use Info level 1 */
1271 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1272 cli
->srv_name_slash
,
1280 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1282 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1284 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1285 cli
->srv_name_slash
,
1295 if (W_ERROR_IS_OK(result
)) {
1296 display_printdriverdir_1(&info
.info1
);
1302 /****************************************************************************
1303 ****************************************************************************/
1305 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1306 struct spoolss_AddDriverInfo3
*info
,
1312 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1314 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1316 info
->version
= archi_table
[i
].version
;
1317 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1322 if (archi_table
[i
].long_archi
== NULL
)
1324 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1331 /**************************************************************************
1332 wrapper for strtok to get the next parameter from a delimited list.
1333 Needed to handle the empty parameter string denoted by "NULL"
1334 *************************************************************************/
1336 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1337 const char *delim
, const char **dest
,
1342 /* get the next token */
1343 ptr
= strtok_r(str
, delim
, saveptr
);
1345 /* a string of 'NULL' is used to represent an empty
1346 parameter because two consecutive delimiters
1347 will not return an empty string. See man strtok(3)
1349 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1354 *dest
= talloc_strdup(mem_ctx
, ptr
);
1360 /********************************************************************************
1361 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1362 string in the form of
1363 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1364 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1365 <Default Data Type>:<Comma Separated list of Files>
1366 *******************************************************************************/
1368 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1373 char *saveptr
= NULL
;
1374 struct spoolss_StringArray
*deps
;
1375 const char **file_array
= NULL
;
1378 /* fill in the UNISTR fields */
1379 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1380 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1381 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1382 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1383 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1384 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1385 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1387 /* <Comma Separated List of Dependent Files> */
1388 /* save the beginning of the string */
1389 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1392 /* begin to strip out each filename */
1393 str
= strtok_r(str
, ",", &saveptr
);
1395 /* no dependent files, we are done */
1400 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1405 while (str
!= NULL
) {
1406 add_string_to_array(deps
, str
, &file_array
, &count
);
1407 str
= strtok_r(NULL
, ",", &saveptr
);
1410 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1411 if (!deps
->string
) {
1415 for (i
=0; i
< count
; i
++) {
1416 deps
->string
[i
] = file_array
[i
];
1419 r
->dependent_files
= deps
;
1424 /****************************************************************************
1425 ****************************************************************************/
1427 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1428 TALLOC_CTX
*mem_ctx
,
1429 int argc
, const char **argv
)
1434 struct spoolss_AddDriverInfoCtr info_ctr
;
1435 struct spoolss_AddDriverInfo3 info3
;
1439 /* parse the command arguments */
1440 if (argc
!= 3 && argc
!= 4)
1442 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1443 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1444 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1445 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1446 printf ("\t[version]\n");
1451 /* Fill in the spoolss_AddDriverInfo3 struct */
1454 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1456 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1457 return WERR_INVALID_PARAM
;
1460 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1462 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1463 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1465 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1466 return WERR_INVALID_PARAM
;
1469 /* if printer driver version specified, override the default version
1470 * used by the architecture. This allows installation of Windows
1471 * 2000 (version 3) printer drivers. */
1474 info3
.version
= atoi(argv
[3]);
1478 info_ctr
.level
= level
;
1479 info_ctr
.info
.info3
= &info3
;
1481 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1482 cli
->srv_name_slash
,
1485 if (!NT_STATUS_IS_OK(status
)) {
1486 return ntstatus_to_werror(status
);
1488 if (W_ERROR_IS_OK(result
)) {
1489 printf ("Printer Driver %s successfully installed.\n",
1497 /****************************************************************************
1498 ****************************************************************************/
1500 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1501 TALLOC_CTX
*mem_ctx
,
1502 int argc
, const char **argv
)
1505 struct spoolss_SetPrinterInfoCtr info_ctr
;
1506 struct spoolss_SetPrinterInfo2 info2
;
1508 /* parse the command arguments */
1511 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1515 /* Fill in the DRIVER_INFO_2 struct */
1518 info2
.printername
= argv
[1];
1519 info2
.drivername
= argv
[3];
1520 info2
.sharename
= argv
[2];
1521 info2
.portname
= argv
[4];
1522 info2
.comment
= "Created by rpcclient";
1523 info2
.printprocessor
= "winprint";
1524 info2
.datatype
= "RAW";
1525 info2
.devmode
= NULL
;
1526 info2
.secdesc
= NULL
;
1527 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1529 info2
.defaultpriority
= 0;
1530 info2
.starttime
= 0;
1531 info2
.untiltime
= 0;
1533 /* These three fields must not be used by AddPrinter()
1534 as defined in the MS Platform SDK documentation..
1538 info2.averageppm = 0;
1542 info_ctr
.info
.info2
= &info2
;
1544 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1546 if (W_ERROR_IS_OK(result
))
1547 printf ("Printer %s successfully installed.\n", argv
[1]);
1552 /****************************************************************************
1553 ****************************************************************************/
1555 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1556 TALLOC_CTX
*mem_ctx
,
1557 int argc
, const char **argv
)
1563 const char *printername
;
1564 union spoolss_PrinterInfo info
;
1565 struct spoolss_SetPrinterInfoCtr info_ctr
;
1566 struct spoolss_DevmodeContainer devmode_ctr
;
1567 struct sec_desc_buf secdesc_ctr
;
1569 ZERO_STRUCT(devmode_ctr
);
1570 ZERO_STRUCT(secdesc_ctr
);
1572 /* parse the command arguments */
1575 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1579 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1581 /* Get a printer handle */
1583 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1587 if (!W_ERROR_IS_OK(result
))
1590 /* Get printer info */
1592 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1597 if (!W_ERROR_IS_OK(result
)) {
1598 printf ("Unable to retrieve printer information!\n");
1602 /* Set the printer driver */
1604 info
.info2
.drivername
= argv
[2];
1605 info
.info2
.devmode
= NULL
;
1606 info
.info2
.secdesc
= NULL
;
1609 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
1611 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1618 if (!W_ERROR_IS_OK(result
)) {
1619 printf("SetPrinter call failed!\n");
1623 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1628 if (is_valid_policy_hnd(&pol
))
1629 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1635 /****************************************************************************
1636 ****************************************************************************/
1638 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1639 TALLOC_CTX
*mem_ctx
,
1640 int argc
, const char **argv
)
1642 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1648 const char *arch
= NULL
;
1649 uint32_t delete_flags
= 0;
1651 /* parse the command arguments */
1652 if (argc
< 2 || argc
> 4) {
1653 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1660 vers
= atoi (argv
[3]);
1663 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1666 /* delete the driver for all architectures */
1667 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1669 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1672 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1675 /* make the call to remove the driver */
1676 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1677 cli
->srv_name_slash
,
1678 archi_table
[i
].long_archi
,
1681 archi_table
[i
].version
,
1684 if ( !W_ERROR_IS_OK(result
) )
1686 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1687 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1688 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1693 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1694 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1703 /****************************************************************************
1704 ****************************************************************************/
1706 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1707 TALLOC_CTX
*mem_ctx
,
1708 int argc
, const char **argv
)
1710 WERROR result
= WERR_OK
;
1714 /* parse the command arguments */
1716 printf ("Usage: %s <driver>\n", argv
[0]);
1720 /* delete the driver for all architectures */
1721 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1722 /* make the call to remove the driver */
1723 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1724 cli
->srv_name_slash
,
1725 archi_table
[i
].long_archi
,
1728 if (!NT_STATUS_IS_OK(status
)) {
1731 if ( !W_ERROR_IS_OK(result
) ) {
1732 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1733 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1734 argv
[1], archi_table
[i
].long_archi
,
1738 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1739 archi_table
[i
].long_archi
);
1746 /****************************************************************************
1747 ****************************************************************************/
1749 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1750 TALLOC_CTX
*mem_ctx
,
1751 int argc
, const char **argv
)
1755 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1758 union spoolss_PrintProcessorDirectoryInfo info
;
1761 /* parse the command arguments */
1763 printf ("Usage: %s [environment]\n", argv
[0]);
1768 environment
= argv
[1];
1771 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1772 cli
->srv_name_slash
,
1780 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1782 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1784 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1785 cli
->srv_name_slash
,
1795 if (W_ERROR_IS_OK(result
)) {
1796 printf("%s\n", info
.info1
.directory_name
);
1802 /****************************************************************************
1803 ****************************************************************************/
1805 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1806 int argc
, const char **argv
)
1811 const char *printername
;
1812 union spoolss_AddFormInfo info
;
1813 struct spoolss_AddFormInfo1 info1
;
1814 struct spoolss_AddFormInfo2 info2
;
1817 /* Parse the command arguments */
1819 if (argc
< 3 || argc
> 5) {
1820 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
1824 /* Get a printer handle */
1826 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1828 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1832 if (!W_ERROR_IS_OK(werror
))
1835 /* Dummy up some values for the form data */
1838 level
= atoi(argv
[3]);
1843 info1
.flags
= SPOOLSS_FORM_USER
;
1844 info1
.form_name
= argv
[2];
1845 info1
.size
.width
= 100;
1846 info1
.size
.height
= 100;
1847 info1
.area
.left
= 0;
1848 info1
.area
.top
= 10;
1849 info1
.area
.right
= 20;
1850 info1
.area
.bottom
= 30;
1852 info
.info1
= &info1
;
1856 info2
.flags
= SPOOLSS_FORM_USER
;
1857 info2
.form_name
= argv
[2];
1858 info2
.size
.width
= 100;
1859 info2
.size
.height
= 100;
1860 info2
.area
.left
= 0;
1861 info2
.area
.top
= 10;
1862 info2
.area
.right
= 20;
1863 info2
.area
.bottom
= 30;
1864 info2
.keyword
= argv
[2];
1865 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
1866 info2
.mui_dll
= NULL
;
1867 info2
.ressource_id
= 0;
1868 info2
.display_name
= argv
[2];
1871 info
.info2
= &info2
;
1879 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
1886 if (is_valid_policy_hnd(&handle
))
1887 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1892 /****************************************************************************
1893 ****************************************************************************/
1895 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1896 int argc
, const char **argv
)
1901 const char *printername
;
1902 union spoolss_AddFormInfo info
;
1903 struct spoolss_AddFormInfo1 info1
;
1905 /* Parse the command arguments */
1908 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1912 /* Get a printer handle */
1914 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1916 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1918 SEC_FLAG_MAXIMUM_ALLOWED
,
1920 if (!W_ERROR_IS_OK(werror
))
1923 /* Dummy up some values for the form data */
1925 info1
.flags
= SPOOLSS_FORM_PRINTER
;
1926 info1
.size
.width
= 100;
1927 info1
.size
.height
= 100;
1928 info1
.area
.left
= 0;
1929 info1
.area
.top
= 1000;
1930 info1
.area
.right
= 2000;
1931 info1
.area
.bottom
= 3000;
1932 info1
.form_name
= argv
[2];
1934 info
.info1
= &info1
;
1938 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
1946 if (is_valid_policy_hnd(&handle
))
1947 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1952 /****************************************************************************
1953 ****************************************************************************/
1955 static const char *get_form_flag(int form_flag
)
1957 switch (form_flag
) {
1958 case SPOOLSS_FORM_USER
:
1960 case SPOOLSS_FORM_BUILTIN
:
1961 return "FORM_BUILTIN";
1962 case SPOOLSS_FORM_PRINTER
:
1963 return "FORM_PRINTER";
1969 /****************************************************************************
1970 ****************************************************************************/
1972 static void display_form_info1(struct spoolss_FormInfo1
*r
)
1975 "\tflag: %s (%d)\n" \
1976 "\twidth: %d, length: %d\n" \
1977 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1978 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
1979 r
->size
.width
, r
->size
.height
,
1980 r
->area
.left
, r
->area
.right
,
1981 r
->area
.top
, r
->area
.bottom
);
1984 /****************************************************************************
1985 ****************************************************************************/
1987 static void display_form_info2(struct spoolss_FormInfo2
*r
)
1990 "\tflag: %s (%d)\n" \
1991 "\twidth: %d, length: %d\n" \
1992 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
1993 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
1994 r
->size
.width
, r
->size
.height
,
1995 r
->area
.left
, r
->area
.right
,
1996 r
->area
.top
, r
->area
.bottom
);
1997 printf("\tkeyword: %s\n", r
->keyword
);
1998 printf("\tstring_type: 0x%08x\n", r
->string_type
);
1999 printf("\tmui_dll: %s\n", r
->mui_dll
);
2000 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2001 printf("\tdisplay_name: %s\n", r
->display_name
);
2002 printf("\tlang_id: %d\n", r
->lang_id
);
2006 /****************************************************************************
2007 ****************************************************************************/
2009 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2010 int argc
, const char **argv
)
2015 const char *printername
;
2017 uint32_t offered
= 0;
2018 union spoolss_FormInfo info
;
2022 /* Parse the command arguments */
2024 if (argc
< 3 || argc
> 5) {
2025 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2029 /* Get a printer handle */
2031 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2033 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2035 SEC_FLAG_MAXIMUM_ALLOWED
,
2037 if (!W_ERROR_IS_OK(werror
))
2041 level
= atoi(argv
[3]);
2046 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2055 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2056 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2058 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2069 if (!NT_STATUS_IS_OK(status
)) {
2075 display_form_info1(&info
.info1
);
2078 display_form_info2(&info
.info2
);
2083 if (is_valid_policy_hnd(&handle
))
2084 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2089 /****************************************************************************
2090 ****************************************************************************/
2092 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2093 TALLOC_CTX
*mem_ctx
, int argc
,
2099 const char *printername
;
2101 /* Parse the command arguments */
2104 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2108 /* Get a printer handle */
2110 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2112 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2114 SEC_FLAG_MAXIMUM_ALLOWED
,
2116 if (!W_ERROR_IS_OK(werror
))
2119 /* Delete the form */
2121 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2125 if (!NT_STATUS_IS_OK(status
)) {
2126 return ntstatus_to_werror(status
);
2130 if (is_valid_policy_hnd(&handle
))
2131 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2136 /****************************************************************************
2137 ****************************************************************************/
2139 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2140 TALLOC_CTX
*mem_ctx
, int argc
,
2145 const char *printername
;
2146 uint32 num_forms
, level
= 1, i
;
2147 union spoolss_FormInfo
*forms
;
2149 /* Parse the command arguments */
2151 if (argc
< 2 || argc
> 4) {
2152 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2156 /* Get a printer handle */
2158 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2160 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2162 SEC_FLAG_MAXIMUM_ALLOWED
,
2164 if (!W_ERROR_IS_OK(werror
))
2168 level
= atoi(argv
[2]);
2171 /* Enumerate forms */
2173 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2180 if (!W_ERROR_IS_OK(werror
))
2183 /* Display output */
2185 for (i
= 0; i
< num_forms
; i
++) {
2188 display_form_info1(&forms
[i
].info1
);
2191 display_form_info2(&forms
[i
].info2
);
2197 if (is_valid_policy_hnd(&handle
))
2198 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2203 /****************************************************************************
2204 ****************************************************************************/
2206 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2207 TALLOC_CTX
*mem_ctx
,
2208 int argc
, const char **argv
)
2211 const char *printername
;
2213 union spoolss_PrinterInfo info
;
2214 REGISTRY_VALUE value
;
2215 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2217 /* parse the command arguments */
2219 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2220 " <value> <data>\n",
2222 result
= WERR_INVALID_PARAM
;
2226 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2228 value
.type
= REG_NONE
;
2230 if (strequal(argv
[2], "string")) {
2231 value
.type
= REG_SZ
;
2234 if (strequal(argv
[2], "binary")) {
2235 value
.type
= REG_BINARY
;
2238 if (strequal(argv
[2], "dword")) {
2239 value
.type
= REG_DWORD
;
2242 if (strequal(argv
[2], "multistring")) {
2243 value
.type
= REG_MULTI_SZ
;
2246 if (value
.type
== REG_NONE
) {
2247 printf("Unknown data type: %s\n", argv
[2]);
2248 result
= WERR_INVALID_PARAM
;
2252 /* get a printer handle */
2254 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2256 SEC_FLAG_MAXIMUM_ALLOWED
,
2258 if (!W_ERROR_IS_OK(result
))
2261 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2266 if (!W_ERROR_IS_OK(result
))
2269 printf("%s\n", current_timestring(tmp_ctx
, True
));
2270 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2272 /* Set the printer data */
2274 fstrcpy(value
.valuename
, argv
[3]);
2276 switch (value
.type
) {
2279 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2280 value
.size
= data
.uni_str_len
* 2;
2282 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, data
.buffer
,
2285 value
.data_p
= NULL
;
2290 uint32 data
= strtoul(argv
[4], NULL
, 10);
2291 value
.size
= sizeof(data
);
2293 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, &data
,
2296 value
.data_p
= NULL
;
2301 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2302 value
.data_p
= data
.data
;
2303 value
.size
= data
.length
;
2306 case REG_MULTI_SZ
: {
2311 for (i
=4; i
<argc
; i
++) {
2312 if (strcmp(argv
[i
], "NULL") == 0) {
2315 len
+= strlen(argv
[i
])+1;
2319 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2320 if (value
.data_p
== NULL
) {
2321 result
= WERR_NOMEM
;
2325 p
= (char *)value
.data_p
;
2327 for (i
=4; i
<argc
; i
++) {
2328 size_t l
= (strlen(argv
[i
])+1)*2;
2329 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2333 SMB_ASSERT(len
== 0);
2337 printf("Unknown data type: %s\n", argv
[2]);
2338 result
= WERR_INVALID_PARAM
;
2342 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2344 if (!W_ERROR_IS_OK(result
)) {
2345 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2348 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2350 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2355 if (!W_ERROR_IS_OK(result
))
2358 printf("%s\n", current_timestring(tmp_ctx
, True
));
2359 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2363 TALLOC_FREE(tmp_ctx
);
2364 if (is_valid_policy_hnd(&pol
))
2365 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2370 /****************************************************************************
2371 ****************************************************************************/
2373 static void display_job_info_1(JOB_INFO_1
*job
)
2375 fstring username
= "", document
= "", text_status
= "";
2377 rpcstr_pull(username
, job
->username
.buffer
,
2378 sizeof(username
), -1, STR_TERMINATE
);
2380 rpcstr_pull(document
, job
->document
.buffer
,
2381 sizeof(document
), -1, STR_TERMINATE
);
2383 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2384 sizeof(text_status
), -1, STR_TERMINATE
);
2386 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2387 username
, document
, text_status
, job
->pagesprinted
,
2391 /****************************************************************************
2392 ****************************************************************************/
2394 static void display_job_info_2(JOB_INFO_2
*job
)
2396 fstring username
= "", document
= "", text_status
= "";
2398 rpcstr_pull(username
, job
->username
.buffer
,
2399 sizeof(username
), -1, STR_TERMINATE
);
2401 rpcstr_pull(document
, job
->document
.buffer
,
2402 sizeof(document
), -1, STR_TERMINATE
);
2404 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2405 sizeof(text_status
), -1, STR_TERMINATE
);
2407 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job
->position
, job
->jobid
,
2408 username
, document
, text_status
, job
->pagesprinted
,
2409 job
->totalpages
, job
->size
);
2412 /****************************************************************************
2413 ****************************************************************************/
2415 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2417 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2418 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2422 /****************************************************************************
2423 ****************************************************************************/
2425 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2427 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2428 r
->position
, r
->job_id
,
2429 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2430 r
->total_pages
, r
->size
);
2433 /****************************************************************************
2434 ****************************************************************************/
2436 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2438 printf("jobid[%d], next_jobid[%d]\n",
2439 r
->job_id
, r
->next_job_id
);
2442 /****************************************************************************
2443 ****************************************************************************/
2445 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2447 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2448 r
->position
, r
->job_id
,
2449 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2450 r
->total_pages
, r
->size
, r
->size_high
);
2453 /****************************************************************************
2454 ****************************************************************************/
2456 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2457 TALLOC_CTX
*mem_ctx
, int argc
,
2461 uint32 level
= 1, num_jobs
, i
;
2462 const char *printername
;
2466 if (argc
< 2 || argc
> 3) {
2467 printf("Usage: %s printername [level]\n", argv
[0]);
2472 level
= atoi(argv
[2]);
2474 /* Open printer handle */
2476 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2478 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2480 SEC_FLAG_MAXIMUM_ALLOWED
,
2482 if (!W_ERROR_IS_OK(result
))
2485 /* Enumerate ports */
2487 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2490 if (!W_ERROR_IS_OK(result
))
2493 for (i
= 0; i
< num_jobs
; i
++) {
2496 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2499 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2502 d_printf("unknown info level %d\n", level
);
2508 if (is_valid_policy_hnd(&hnd
))
2509 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2514 /****************************************************************************
2515 ****************************************************************************/
2517 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2518 TALLOC_CTX
*mem_ctx
, int argc
,
2522 const char *printername
;
2523 struct policy_handle hnd
;
2526 union spoolss_JobInfo info
;
2528 if (argc
< 3 || argc
> 4) {
2529 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2533 job_id
= atoi(argv
[2]);
2536 level
= atoi(argv
[3]);
2539 /* Open printer handle */
2541 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2543 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2545 SEC_FLAG_MAXIMUM_ALLOWED
,
2547 if (!W_ERROR_IS_OK(result
)) {
2551 /* Enumerate ports */
2553 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2560 if (!W_ERROR_IS_OK(result
)) {
2566 display_job_info1(&info
.info1
);
2569 display_job_info2(&info
.info2
);
2572 display_job_info3(&info
.info3
);
2575 display_job_info4(&info
.info4
);
2578 d_printf("unknown info level %d\n", level
);
2583 if (is_valid_policy_hnd(&hnd
)) {
2584 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2591 /****************************************************************************
2592 ****************************************************************************/
2594 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2595 TALLOC_CTX
*mem_ctx
, int argc
,
2599 uint32 i
=0, val_needed
, data_needed
;
2600 const char *printername
;
2604 printf("Usage: %s printername\n", argv
[0]);
2608 /* Open printer handle */
2610 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2612 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2614 SEC_FLAG_MAXIMUM_ALLOWED
,
2616 if (!W_ERROR_IS_OK(result
))
2619 /* Enumerate data */
2621 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2622 &val_needed
, &data_needed
,
2624 while (W_ERROR_IS_OK(result
)) {
2625 REGISTRY_VALUE value
;
2626 result
= rpccli_spoolss_enumprinterdata(
2627 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2628 data_needed
, 0, 0, &value
);
2629 if (W_ERROR_IS_OK(result
))
2630 display_reg_value(value
);
2632 if (W_ERROR_V(result
) == ERRnomoreitems
)
2633 result
= W_ERROR(ERRsuccess
);
2636 if (is_valid_policy_hnd(&hnd
))
2637 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2642 /****************************************************************************
2643 ****************************************************************************/
2645 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2646 TALLOC_CTX
*mem_ctx
, int argc
,
2651 const char *printername
;
2652 const char *keyname
= NULL
;
2654 REGVAL_CTR
*ctr
= NULL
;
2657 printf("Usage: %s printername <keyname>\n", argv
[0]);
2663 /* Open printer handle */
2665 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2667 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2669 SEC_FLAG_MAXIMUM_ALLOWED
,
2671 if (!W_ERROR_IS_OK(result
))
2674 /* Enumerate subkeys */
2676 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2679 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2681 if (!W_ERROR_IS_OK(result
))
2684 for (i
=0; i
< ctr
->num_values
; i
++) {
2685 display_reg_value(*(ctr
->values
[i
]));
2691 if (is_valid_policy_hnd(&hnd
))
2692 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2697 /****************************************************************************
2698 ****************************************************************************/
2700 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2701 TALLOC_CTX
*mem_ctx
, int argc
,
2705 const char *printername
;
2706 const char *keyname
= NULL
;
2708 uint16
*keylist
= NULL
, *curkey
;
2710 if (argc
< 2 || argc
> 3) {
2711 printf("Usage: %s printername [keyname]\n", argv
[0]);
2720 /* Open printer handle */
2722 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2724 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2726 SEC_FLAG_MAXIMUM_ALLOWED
,
2728 if (!W_ERROR_IS_OK(result
))
2731 /* Enumerate subkeys */
2733 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2735 if (!W_ERROR_IS_OK(result
))
2739 while (*curkey
!= 0) {
2740 char *subkey
= NULL
;
2741 rpcstr_pull_talloc(mem_ctx
, &subkey
, curkey
, -1,
2746 printf("%s\n", subkey
);
2747 curkey
+= strlen(subkey
) + 1;
2754 if (is_valid_policy_hnd(&hnd
))
2755 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2760 /****************************************************************************
2761 ****************************************************************************/
2763 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2764 TALLOC_CTX
*mem_ctx
, int argc
,
2767 const char *printername
;
2768 const char *clientname
;
2772 struct spoolss_NotifyOption option
;
2775 printf("Usage: %s printername\n", argv
[0]);
2782 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2784 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2786 SEC_FLAG_MAXIMUM_ALLOWED
,
2788 if (!W_ERROR_IS_OK(result
)) {
2789 printf("Error opening %s\n", argv
[1]);
2793 /* Create spool options */
2798 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
2799 if (option
.types
== NULL
) {
2800 result
= WERR_NOMEM
;
2804 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
2805 option
.types
[0].count
= 1;
2806 option
.types
[0].fields
= talloc_array(mem_ctx
, enum spoolss_Field
, 1);
2807 if (option
.types
[0].fields
== NULL
) {
2808 result
= WERR_NOMEM
;
2811 option
.types
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2813 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
2814 option
.types
[1].count
= 1;
2815 option
.types
[1].fields
= talloc_array(mem_ctx
, enum spoolss_Field
, 1);
2816 if (option
.types
[1].fields
== NULL
) {
2817 result
= WERR_NOMEM
;
2820 option
.types
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2822 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
2824 result
= WERR_NOMEM
;
2830 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
2838 if (!W_ERROR_IS_OK(result
)) {
2839 printf("Error rffpcnex %s\n", argv
[1]);
2844 if (is_valid_policy_hnd(&hnd
))
2845 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2850 /****************************************************************************
2851 ****************************************************************************/
2853 static bool compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2854 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2856 union spoolss_PrinterInfo info1
, info2
;
2858 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2860 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
2861 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
2866 if ( !W_ERROR_IS_OK(werror
) ) {
2867 printf("failed (%s)\n", win_errstr(werror
));
2868 talloc_destroy(mem_ctx
);
2873 printf("Retrieving printer properties for %s...", cli2
->desthost
);
2874 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
2879 if ( !W_ERROR_IS_OK(werror
) ) {
2880 printf("failed (%s)\n", win_errstr(werror
));
2881 talloc_destroy(mem_ctx
);
2886 talloc_destroy(mem_ctx
);
2891 /****************************************************************************
2892 ****************************************************************************/
2894 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2895 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2897 union spoolss_PrinterInfo info1
, info2
;
2899 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2900 SEC_DESC
*sd1
, *sd2
;
2904 printf("Retrieving printer security for %s...", cli1
->desthost
);
2905 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
2910 if ( !W_ERROR_IS_OK(werror
) ) {
2911 printf("failed (%s)\n", win_errstr(werror
));
2917 printf("Retrieving printer security for %s...", cli2
->desthost
);
2918 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
2923 if ( !W_ERROR_IS_OK(werror
) ) {
2924 printf("failed (%s)\n", win_errstr(werror
));
2933 sd1
= info1
.info3
.secdesc
;
2934 sd2
= info2
.info3
.secdesc
;
2936 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2937 printf("NULL secdesc!\n");
2942 if (!sec_desc_equal( sd1
, sd2
) ) {
2943 printf("Security Descriptors *not* equal!\n");
2948 printf("Security descriptors match\n");
2951 talloc_destroy(mem_ctx
);
2956 /****************************************************************************
2957 ****************************************************************************/
2959 extern struct user_auth_info
*rpcclient_auth_info
;
2961 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2962 TALLOC_CTX
*mem_ctx
, int argc
,
2965 const char *printername
;
2966 char *printername_path
= NULL
;
2967 struct cli_state
*cli_server2
= NULL
;
2968 struct rpc_pipe_client
*cli2
= NULL
;
2969 POLICY_HND hPrinter1
, hPrinter2
;
2974 printf("Usage: %s <printer> <server>\n", argv
[0]);
2978 printername
= argv
[1];
2980 /* first get the connection to the remote server */
2982 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
2985 get_cmdline_auth_info_username(rpcclient_auth_info
),
2987 get_cmdline_auth_info_password(rpcclient_auth_info
),
2988 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2989 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
2991 if ( !NT_STATUS_IS_OK(nt_status
) )
2992 return WERR_GENERAL_FAILURE
;
2994 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &syntax_spoolss
,
2996 if (!NT_STATUS_IS_OK(nt_status
)) {
2997 printf("failed to open spoolss pipe on server %s (%s)\n",
2998 argv
[2], nt_errstr(nt_status
));
2999 return WERR_GENERAL_FAILURE
;
3002 /* now open up both printers */
3004 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3006 printf("Opening %s...", printername_path
);
3008 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3012 if ( !W_ERROR_IS_OK(werror
) ) {
3013 printf("failed (%s)\n", win_errstr(werror
));
3018 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3020 printf("Opening %s...", printername_path
);
3021 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3025 if ( !W_ERROR_IS_OK(werror
) ) {
3026 printf("failed (%s)\n", win_errstr(werror
));
3031 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3032 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3034 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3041 printf("Closing printers...");
3042 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3043 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3046 /* close the second remote connection */
3048 cli_shutdown( cli_server2
);
3052 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3054 printf("print_processor_name: %s\n", r
->print_processor_name
);
3057 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3058 TALLOC_CTX
*mem_ctx
, int argc
,
3062 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3063 uint32_t num_procs
, level
= 1, i
;
3064 union spoolss_PrintProcessorInfo
*procs
;
3066 /* Parse the command arguments */
3068 if (argc
< 1 || argc
> 4) {
3069 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3074 environment
= argv
[1];
3078 level
= atoi(argv
[2]);
3081 /* Enumerate Print Processors */
3083 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3084 cli
->srv_name_slash
,
3090 if (!W_ERROR_IS_OK(werror
))
3093 /* Display output */
3095 for (i
= 0; i
< num_procs
; i
++) {
3098 display_proc_info1(&procs
[i
].info1
);
3107 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3109 printf("name_array: %s\n", r
->name_array
);
3112 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3113 TALLOC_CTX
*mem_ctx
, int argc
,
3117 const char *print_processor_name
= "winprint";
3118 uint32_t num_procs
, level
= 1, i
;
3119 union spoolss_PrintProcDataTypesInfo
*procs
;
3121 /* Parse the command arguments */
3123 if (argc
< 1 || argc
> 4) {
3124 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3129 print_processor_name
= argv
[1];
3133 level
= atoi(argv
[2]);
3136 /* Enumerate Print Processor Data Types */
3138 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3139 cli
->srv_name_slash
,
3140 print_processor_name
,
3145 if (!W_ERROR_IS_OK(werror
))
3148 /* Display output */
3150 for (i
= 0; i
< num_procs
; i
++) {
3153 display_proc_data_types_info1(&procs
[i
].info1
);
3162 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3164 printf("monitor_name: %s\n", r
->monitor_name
);
3167 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3169 printf("monitor_name: %s\n", r
->monitor_name
);
3170 printf("environment: %s\n", r
->environment
);
3171 printf("dll_name: %s\n", r
->dll_name
);
3174 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3175 TALLOC_CTX
*mem_ctx
, int argc
,
3179 uint32_t count
, level
= 1, i
;
3180 union spoolss_MonitorInfo
*info
;
3182 /* Parse the command arguments */
3185 printf("Usage: %s [level]\n", argv
[0]);
3190 level
= atoi(argv
[1]);
3193 /* Enumerate Print Monitors */
3195 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3196 cli
->srv_name_slash
,
3201 if (!W_ERROR_IS_OK(werror
)) {
3205 /* Display output */
3207 for (i
= 0; i
< count
; i
++) {
3210 display_monitor1(&info
[i
].info1
);
3213 display_monitor2(&info
[i
].info2
);
3222 /* List of commands exported by this module */
3223 struct cmd_set spoolss_commands
[] = {
3227 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &syntax_spoolss
, NULL
, "Add a print driver", "" },
3228 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &syntax_spoolss
, NULL
, "Add a printer", "" },
3229 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &syntax_spoolss
, NULL
, "Delete a printer driver", "" },
3230 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &syntax_spoolss
, NULL
, "Delete a printer driver with files", "" },
3231 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &syntax_spoolss
, NULL
, "Enumerate printer data", "" },
3232 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &syntax_spoolss
, NULL
, "Enumerate printer data for a key", "" },
3233 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &syntax_spoolss
, NULL
, "Enumerate printer keys", "" },
3234 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &syntax_spoolss
, NULL
, "Enumerate print jobs", "" },
3235 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &syntax_spoolss
, NULL
, "Get print job", "" },
3236 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &syntax_spoolss
, NULL
, "Enumerate printer ports", "" },
3237 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &syntax_spoolss
, NULL
, "Enumerate installed printer drivers", "" },
3238 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &syntax_spoolss
, NULL
, "Enumerate printers", "" },
3239 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &syntax_spoolss
, NULL
, "Get print driver data", "" },
3240 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &syntax_spoolss
, NULL
, "Get printer driver data with keyname", ""},
3241 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &syntax_spoolss
, NULL
, "Get print driver information", "" },
3242 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &syntax_spoolss
, NULL
, "Get print driver upload directory", "" },
3243 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &syntax_spoolss
, NULL
, "Get printer info", "" },
3244 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &syntax_spoolss
, NULL
, "Open printer handle", "" },
3245 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &syntax_spoolss
, NULL
, "Set printer driver", "" },
3246 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &syntax_spoolss
, NULL
, "Get print processor directory", "" },
3247 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &syntax_spoolss
, NULL
, "Add form", "" },
3248 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &syntax_spoolss
, NULL
, "Set form", "" },
3249 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &syntax_spoolss
, NULL
, "Get form", "" },
3250 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &syntax_spoolss
, NULL
, "Delete form", "" },
3251 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &syntax_spoolss
, NULL
, "Enumerate forms", "" },
3252 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &syntax_spoolss
, NULL
, "Set printer comment", "" },
3253 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &syntax_spoolss
, NULL
, "Set printername", "" },
3254 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &syntax_spoolss
, NULL
, "Set REG_SZ printer data", "" },
3255 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &syntax_spoolss
, NULL
, "Rffpcnex test", "" },
3256 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &syntax_spoolss
, NULL
, "Printer comparison test", "" },
3257 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &syntax_spoolss
, NULL
, "Enumerate Print Processors", "" },
3258 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &syntax_spoolss
, NULL
, "Enumerate Print Processor Data Types", "" },
3259 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &syntax_spoolss
, NULL
, "Enumerate Print Monitors", "" },