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(PORT_INFO_1
*i1
)
366 rpcstr_pull(buffer
, i1
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
367 printf("\tPort Name:\t[%s]\n", buffer
);
370 /****************************************************************************
371 ****************************************************************************/
373 static void display_port_info_2(PORT_INFO_2
*i2
)
377 rpcstr_pull(buffer
, i2
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
378 printf("\tPort Name:\t[%s]\n", buffer
);
379 rpcstr_pull(buffer
, i2
->monitor_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
381 printf("\tMonitor Name:\t[%s]\n", buffer
);
382 rpcstr_pull(buffer
, i2
->description
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
384 printf("\tDescription:\t[%s]\n", buffer
);
385 printf("\tPort Type:\t" );
386 if ( i2
->port_type
) {
387 int comma
= 0; /* hack */
389 if ( i2
->port_type
& PORT_TYPE_READ
) {
393 if ( i2
->port_type
& PORT_TYPE_WRITE
) {
394 printf( "%sWrite", comma
? ", " : "" );
397 /* These two have slightly different interpretations
398 on 95/98/ME but I'm disregarding that for now */
399 if ( i2
->port_type
& PORT_TYPE_REDIRECTED
) {
400 printf( "%sRedirected", comma
? ", " : "" );
403 if ( i2
->port_type
& PORT_TYPE_NET_ATTACHED
) {
404 printf( "%sNet-Attached", comma
? ", " : "" );
408 printf( "[Unset]\n" );
410 printf("\tReserved:\t[%d]\n", i2
->reserved
);
414 /****************************************************************************
415 ****************************************************************************/
417 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
418 TALLOC_CTX
*mem_ctx
, int argc
,
422 uint32 info_level
= 1;
427 printf("Usage: %s [level]\n", argv
[0]);
432 info_level
= atoi(argv
[1]);
434 /* Enumerate ports */
438 result
= rpccli_spoolss_enum_ports(cli
, mem_ctx
, info_level
, &returned
, &ctr
);
440 if (W_ERROR_IS_OK(result
)) {
443 for (i
= 0; i
< returned
; i
++) {
444 switch (info_level
) {
446 display_port_info_1(&ctr
.port
.info_1
[i
]);
449 display_port_info_2(&ctr
.port
.info_2
[i
]);
452 printf("unknown info level %d\n", info_level
);
461 /****************************************************************************
462 ****************************************************************************/
464 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
466 int argc
, const char **argv
)
471 uint32 info_level
= 2;
472 union spoolss_PrinterInfo info
;
473 struct spoolss_SetPrinterInfoCtr info_ctr
;
474 const char *printername
, *comment
= NULL
;
475 struct spoolss_DevmodeContainer devmode_ctr
;
476 struct sec_desc_buf secdesc_ctr
;
478 if (argc
== 1 || argc
> 3) {
479 printf("Usage: %s printername comment\n", argv
[0]);
484 /* Open a printer handle */
489 ZERO_STRUCT(devmode_ctr
);
490 ZERO_STRUCT(secdesc_ctr
);
492 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
494 /* get a printer handle */
495 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
499 if (!W_ERROR_IS_OK(result
))
502 /* Get printer info */
503 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
508 if (!W_ERROR_IS_OK(result
))
512 /* Modify the comment. */
513 info
.info2
.comment
= comment
;
514 info
.info2
.secdesc
= NULL
;
515 info
.info2
.devmode
= NULL
;
518 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
520 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
527 if (W_ERROR_IS_OK(result
))
528 printf("Success in setting comment.\n");
531 if (is_valid_policy_hnd(&pol
))
532 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
537 /****************************************************************************
538 ****************************************************************************/
540 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
542 int argc
, const char **argv
)
547 uint32 info_level
= 2;
548 union spoolss_PrinterInfo info
;
549 const char *printername
,
550 *new_printername
= NULL
;
551 struct spoolss_SetPrinterInfoCtr info_ctr
;
552 struct spoolss_DevmodeContainer devmode_ctr
;
553 struct sec_desc_buf secdesc_ctr
;
555 ZERO_STRUCT(devmode_ctr
);
556 ZERO_STRUCT(secdesc_ctr
);
558 if (argc
== 1 || argc
> 3) {
559 printf("Usage: %s printername new_printername\n", argv
[0]);
564 /* Open a printer handle */
566 new_printername
= argv
[2];
569 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
571 /* get a printer handle */
572 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
576 if (!W_ERROR_IS_OK(result
))
579 /* Get printer info */
580 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
585 if (!W_ERROR_IS_OK(result
))
588 /* Modify the printername. */
589 info
.info2
.printername
= new_printername
;
590 info
.info2
.devmode
= NULL
;
591 info
.info2
.secdesc
= NULL
;
593 info_ctr
.level
= info_level
;
594 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
596 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
603 if (W_ERROR_IS_OK(result
))
604 printf("Success in setting printername.\n");
607 if (is_valid_policy_hnd(&pol
))
608 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
613 /****************************************************************************
614 ****************************************************************************/
616 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
618 int argc
, const char **argv
)
622 uint32 info_level
= 1;
623 const char *printername
;
624 union spoolss_PrinterInfo info
;
626 if (argc
== 1 || argc
> 3) {
627 printf("Usage: %s <printername> [level]\n", argv
[0]);
631 /* Open a printer handle */
633 info_level
= atoi(argv
[2]);
636 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
638 /* get a printer handle */
640 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
642 SEC_FLAG_MAXIMUM_ALLOWED
,
644 if (!W_ERROR_IS_OK(result
))
647 /* Get printer info */
649 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
654 if (!W_ERROR_IS_OK(result
))
657 /* Display printer info */
658 switch (info_level
) {
661 display_print_info_0(ctr
.printers_0
);
664 display_print_info_1(ctr
.printers_1
);
667 display_print_info_2(ctr
.printers_2
);
670 display_print_info_3(ctr
.printers_3
);
674 display_print_info7(&info
.info7
);
677 printf("unknown info level %d\n", info_level
);
681 if (is_valid_policy_hnd(&pol
))
682 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
687 /****************************************************************************
688 ****************************************************************************/
690 static void display_reg_value(REGISTRY_VALUE value
)
696 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
697 *((uint32
*) value
.data_p
));
700 rpcstr_pull_talloc(talloc_tos(),
705 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
708 char *hex
= hex_encode_talloc(NULL
, value
.data_p
, value
.size
);
710 printf("%s: REG_BINARY:", value
.valuename
);
712 for (i
=0; i
<len
; i
++) {
713 if (hex
[i
] == '\0') {
726 uint32 i
, num_values
;
729 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL
, value
.data_p
,
730 value
.size
, &num_values
,
732 d_printf("reg_pull_multi_sz failed\n");
736 for (i
=0; i
<num_values
; i
++) {
737 d_printf("%s\n", values
[i
]);
743 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
748 /****************************************************************************
749 ****************************************************************************/
751 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
753 int argc
, const char **argv
)
758 const char *valuename
;
759 REGISTRY_VALUE value
;
762 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
763 printf("<printername> of . queries print server\n");
768 /* Open a printer handle */
770 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
771 fstrcpy(printername
, cli
->srv_name_slash
);
773 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
774 cli
->srv_name_slash
, argv
[1]);
776 /* get a printer handle */
778 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
780 SEC_FLAG_MAXIMUM_ALLOWED
,
782 if (!W_ERROR_IS_OK(result
))
785 /* Get printer info */
787 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
789 if (!W_ERROR_IS_OK(result
))
792 /* Display printer data */
794 fstrcpy(value
.valuename
, valuename
);
795 display_reg_value(value
);
799 if (is_valid_policy_hnd(&pol
))
800 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
805 /****************************************************************************
806 ****************************************************************************/
808 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
810 int argc
, const char **argv
)
816 const char *valuename
, *keyname
;
817 REGISTRY_VALUE value
;
820 uint8_t *buffer
= NULL
;
821 uint32_t offered
= 0;
825 printf("Usage: %s <printername> <keyname> <valuename>\n",
827 printf("<printername> of . queries print server\n");
833 /* Open a printer handle */
835 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
836 fstrcpy(printername
, cli
->srv_name_slash
);
838 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
839 cli
->srv_name_slash
, argv
[1]);
841 /* get a printer handle */
843 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
845 SEC_FLAG_MAXIMUM_ALLOWED
,
847 if (!W_ERROR_IS_OK(result
))
850 /* Get printer info */
852 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
861 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
863 buffer
= talloc_array(mem_ctx
, uint8_t, needed
);
864 status
= rpccli_spoolss_GetPrinterDataEx(cli
, mem_ctx
,
875 if (!NT_STATUS_IS_OK(status
)) {
879 if (!W_ERROR_IS_OK(result
)) {
884 if (!W_ERROR_IS_OK(result
))
887 /* Display printer data */
889 fstrcpy(value
.valuename
, valuename
);
892 value
.data_p
= buffer
;
894 display_reg_value(value
);
897 if (is_valid_policy_hnd(&pol
))
898 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
903 /****************************************************************************
904 ****************************************************************************/
906 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
912 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
914 printf ("Printer Driver Info 1:\n");
915 printf ("\tDriver Name: [%s]\n\n", name
);
920 /****************************************************************************
921 ****************************************************************************/
923 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
926 fstring architecture
;
933 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
934 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
935 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
936 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
937 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
939 printf ("Printer Driver Info 2:\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\n", configfile
);
950 /****************************************************************************
951 ****************************************************************************/
953 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
956 fstring architecture
= "";
957 fstring driverpath
= "";
958 fstring datafile
= "";
959 fstring configfile
= "";
960 fstring helpfile
= "";
961 fstring dependentfiles
= "";
962 fstring monitorname
= "";
963 fstring defaultdatatype
= "";
971 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
972 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
973 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
974 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
975 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
976 rpcstr_pull(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
), -1, STR_TERMINATE
);
977 rpcstr_pull(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
), -1, STR_TERMINATE
);
978 rpcstr_pull(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
), -1, STR_TERMINATE
);
980 printf ("Printer Driver Info 3:\n");
981 printf ("\tVersion: [%x]\n", i1
->version
);
982 printf ("\tDriver Name: [%s]\n",name
);
983 printf ("\tArchitecture: [%s]\n", architecture
);
984 printf ("\tDriver Path: [%s]\n", driverpath
);
985 printf ("\tDatafile: [%s]\n", datafile
);
986 printf ("\tConfigfile: [%s]\n", configfile
);
987 printf ("\tHelpfile: [%s]\n\n", helpfile
);
991 rpcstr_pull(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
), -1, STR_TERMINATE
);
993 length
+=strlen(dependentfiles
)+1;
995 if (strlen(dependentfiles
) > 0)
997 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
1007 printf ("\tMonitorname: [%s]\n", monitorname
);
1008 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
1013 /****************************************************************************
1014 ****************************************************************************/
1016 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1022 printf("Printer Driver Info 1:\n");
1023 printf("\tDriver Name: [%s]\n\n", r
->driver_name
);
1026 /****************************************************************************
1027 ****************************************************************************/
1029 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1035 printf("Printer Driver Info 2:\n");
1036 printf("\tVersion: [%x]\n", r
->version
);
1037 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1038 printf("\tArchitecture: [%s]\n", r
->architecture
);
1039 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1040 printf("\tDatafile: [%s]\n", r
->data_file
);
1041 printf("\tConfigfile: [%s]\n\n", r
->config_file
);
1044 /****************************************************************************
1045 ****************************************************************************/
1047 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1055 printf("Printer Driver Info 3:\n");
1056 printf("\tVersion: [%x]\n", r
->version
);
1057 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1058 printf("\tArchitecture: [%s]\n", r
->architecture
);
1059 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1060 printf("\tDatafile: [%s]\n", r
->data_file
);
1061 printf("\tConfigfile: [%s]\n\n", r
->config_file
);
1062 printf("\tHelpfile: [%s]\n\n", r
->help_file
);
1064 for (i
=0; r
->dependent_files
[i
] != NULL
; i
++) {
1065 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1070 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1071 printf("\tDefaultdatatype: [%s]\n\n", r
->default_datatype
);
1075 /****************************************************************************
1076 ****************************************************************************/
1078 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1079 TALLOC_CTX
*mem_ctx
,
1080 int argc
, const char **argv
)
1084 uint32 info_level
= 3;
1085 const char *printername
;
1087 bool success
= False
;
1088 union spoolss_DriverInfo info
;
1089 uint32_t server_major_version
;
1090 uint32_t server_minor_version
;
1092 if ((argc
== 1) || (argc
> 3))
1094 printf("Usage: %s <printername> [level]\n", argv
[0]);
1098 /* get the arguments need to open the printer handle */
1100 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1103 info_level
= atoi(argv
[2]);
1105 /* Open a printer handle */
1107 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1111 if (!W_ERROR_IS_OK(werror
)) {
1112 printf("Error opening printer handle for %s!\n", printername
);
1116 /* loop through and print driver info level for each architecture */
1118 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1120 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1122 archi_table
[i
].long_archi
,
1125 archi_table
[i
].version
,
1128 &server_major_version
,
1129 &server_minor_version
);
1130 if (!W_ERROR_IS_OK(werror
))
1133 /* need at least one success */
1137 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1139 switch (info_level
) {
1141 display_print_driver1(&info
.info1
);
1144 display_print_driver2(&info
.info2
);
1147 display_print_driver3(&info
.info3
);
1150 printf("unknown info level %d\n", info_level
);
1157 if (is_valid_policy_hnd(&pol
))
1158 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1166 /****************************************************************************
1167 ****************************************************************************/
1169 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1170 TALLOC_CTX
*mem_ctx
,
1171 int argc
, const char **argv
)
1173 WERROR werror
= WERR_OK
;
1174 uint32 info_level
= 1;
1175 PRINTER_DRIVER_CTR ctr
;
1180 printf("Usage: enumdrivers [level]\n");
1185 info_level
= atoi(argv
[1]);
1188 /* loop through and print driver info level for each architecture */
1189 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1190 /* check to see if we already asked for this architecture string */
1192 if ( i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
) )
1195 werror
= rpccli_spoolss_enumprinterdrivers(
1196 cli
, mem_ctx
, info_level
,
1197 archi_table
[i
].long_archi
, &returned
, &ctr
);
1199 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1200 printf ("Server does not support environment [%s]\n",
1201 archi_table
[i
].long_archi
);
1209 if (!W_ERROR_IS_OK(werror
)) {
1210 printf ("Error getting driver for environment [%s] - %d\n",
1211 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1215 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1220 for (j
=0; j
< returned
; j
++) {
1221 display_print_driver_1 (&ctr
.info1
[j
]);
1225 for (j
=0; j
< returned
; j
++) {
1226 display_print_driver_2 (&ctr
.info2
[j
]);
1230 for (j
=0; j
< returned
; j
++) {
1231 display_print_driver_3 (&ctr
.info3
[j
]);
1235 printf("unknown info level %d\n", info_level
);
1236 return WERR_UNKNOWN_LEVEL
;
1243 /****************************************************************************
1244 ****************************************************************************/
1246 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1248 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1251 /****************************************************************************
1252 ****************************************************************************/
1254 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1255 TALLOC_CTX
*mem_ctx
,
1256 int argc
, const char **argv
)
1260 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1263 union spoolss_DriverDirectoryInfo info
;
1267 printf("Usage: %s [environment]\n", argv
[0]);
1271 /* Get the arguments need to open the printer handle */
1277 /* Get the directory. Only use Info level 1 */
1279 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1280 cli
->srv_name_slash
,
1288 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1290 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1292 status
= rpccli_spoolss_GetPrinterDriverDirectory(cli
, mem_ctx
,
1293 cli
->srv_name_slash
,
1303 if (W_ERROR_IS_OK(result
)) {
1304 display_printdriverdir_1(&info
.info1
);
1310 /****************************************************************************
1311 ****************************************************************************/
1313 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1314 struct spoolss_AddDriverInfo3
*info
,
1320 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1322 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1324 info
->version
= archi_table
[i
].version
;
1325 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1330 if (archi_table
[i
].long_archi
== NULL
)
1332 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1339 /**************************************************************************
1340 wrapper for strtok to get the next parameter from a delimited list.
1341 Needed to handle the empty parameter string denoted by "NULL"
1342 *************************************************************************/
1344 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1345 const char *delim
, const char **dest
,
1350 /* get the next token */
1351 ptr
= strtok_r(str
, delim
, saveptr
);
1353 /* a string of 'NULL' is used to represent an empty
1354 parameter because two consecutive delimiters
1355 will not return an empty string. See man strtok(3)
1357 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0)) {
1362 *dest
= talloc_strdup(mem_ctx
, ptr
);
1368 /********************************************************************************
1369 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1370 string in the form of
1371 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1372 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1373 <Default Data Type>:<Comma Separated list of Files>
1374 *******************************************************************************/
1376 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1381 char *saveptr
= NULL
;
1382 struct spoolss_StringArray
*deps
;
1383 const char **file_array
= NULL
;
1386 /* fill in the UNISTR fields */
1387 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1388 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1389 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1390 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1391 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1392 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1393 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1395 /* <Comma Separated List of Dependent Files> */
1396 /* save the beginning of the string */
1397 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1400 /* begin to strip out each filename */
1401 str
= strtok_r(str
, ",", &saveptr
);
1403 /* no dependent files, we are done */
1408 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1413 while (str
!= NULL
) {
1414 add_string_to_array(deps
, str
, &file_array
, &count
);
1415 str
= strtok_r(NULL
, ",", &saveptr
);
1418 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1419 if (!deps
->string
) {
1423 for (i
=0; i
< count
; i
++) {
1424 deps
->string
[i
] = file_array
[i
];
1427 r
->dependent_files
= deps
;
1432 /****************************************************************************
1433 ****************************************************************************/
1435 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1436 TALLOC_CTX
*mem_ctx
,
1437 int argc
, const char **argv
)
1442 struct spoolss_AddDriverInfoCtr info_ctr
;
1443 struct spoolss_AddDriverInfo3 info3
;
1447 /* parse the command arguments */
1448 if (argc
!= 3 && argc
!= 4)
1450 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1451 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1452 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1453 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1454 printf ("\t[version]\n");
1459 /* Fill in the spoolss_AddDriverInfo3 struct */
1462 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1464 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1465 return WERR_INVALID_PARAM
;
1468 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1470 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1471 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1473 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1474 return WERR_INVALID_PARAM
;
1477 /* if printer driver version specified, override the default version
1478 * used by the architecture. This allows installation of Windows
1479 * 2000 (version 3) printer drivers. */
1482 info3
.version
= atoi(argv
[3]);
1486 info_ctr
.level
= level
;
1487 info_ctr
.info
.info3
= &info3
;
1489 status
= rpccli_spoolss_AddPrinterDriver(cli
, mem_ctx
,
1490 cli
->srv_name_slash
,
1493 if (!NT_STATUS_IS_OK(status
)) {
1494 return ntstatus_to_werror(status
);
1496 if (W_ERROR_IS_OK(result
)) {
1497 printf ("Printer Driver %s successfully installed.\n",
1505 /****************************************************************************
1506 ****************************************************************************/
1508 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1509 TALLOC_CTX
*mem_ctx
,
1510 int argc
, const char **argv
)
1513 struct spoolss_SetPrinterInfoCtr info_ctr
;
1514 struct spoolss_SetPrinterInfo2 info2
;
1516 /* parse the command arguments */
1519 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1523 /* Fill in the DRIVER_INFO_2 struct */
1526 info2
.printername
= argv
[1];
1527 info2
.drivername
= argv
[3];
1528 info2
.sharename
= argv
[2];
1529 info2
.portname
= argv
[4];
1530 info2
.comment
= "Created by rpcclient";
1531 info2
.printprocessor
= "winprint";
1532 info2
.datatype
= "RAW";
1533 info2
.devmode
= NULL
;
1534 info2
.secdesc
= NULL
;
1535 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1537 info2
.defaultpriority
= 0;
1538 info2
.starttime
= 0;
1539 info2
.untiltime
= 0;
1541 /* These three fields must not be used by AddPrinter()
1542 as defined in the MS Platform SDK documentation..
1546 info2.averageppm = 0;
1550 info_ctr
.info
.info2
= &info2
;
1552 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1554 if (W_ERROR_IS_OK(result
))
1555 printf ("Printer %s successfully installed.\n", argv
[1]);
1560 /****************************************************************************
1561 ****************************************************************************/
1563 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1564 TALLOC_CTX
*mem_ctx
,
1565 int argc
, const char **argv
)
1571 const char *printername
;
1572 union spoolss_PrinterInfo info
;
1573 struct spoolss_SetPrinterInfoCtr info_ctr
;
1574 struct spoolss_DevmodeContainer devmode_ctr
;
1575 struct sec_desc_buf secdesc_ctr
;
1577 ZERO_STRUCT(devmode_ctr
);
1578 ZERO_STRUCT(secdesc_ctr
);
1580 /* parse the command arguments */
1583 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1587 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1589 /* Get a printer handle */
1591 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1595 if (!W_ERROR_IS_OK(result
))
1598 /* Get printer info */
1600 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1605 if (!W_ERROR_IS_OK(result
)) {
1606 printf ("Unable to retrieve printer information!\n");
1610 /* Set the printer driver */
1612 info
.info2
.drivername
= argv
[2];
1613 info
.info2
.devmode
= NULL
;
1614 info
.info2
.secdesc
= NULL
;
1617 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
.info2
;
1619 status
= rpccli_spoolss_SetPrinter(cli
, mem_ctx
,
1626 if (!W_ERROR_IS_OK(result
)) {
1627 printf("SetPrinter call failed!\n");
1631 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1636 if (is_valid_policy_hnd(&pol
))
1637 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
1643 /****************************************************************************
1644 ****************************************************************************/
1646 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1647 TALLOC_CTX
*mem_ctx
,
1648 int argc
, const char **argv
)
1650 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1656 const char *arch
= NULL
;
1657 uint32_t delete_flags
= 0;
1659 /* parse the command arguments */
1660 if (argc
< 2 || argc
> 4) {
1661 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1668 vers
= atoi (argv
[3]);
1671 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1674 /* delete the driver for all architectures */
1675 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1677 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1680 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1683 /* make the call to remove the driver */
1684 status
= rpccli_spoolss_DeletePrinterDriverEx(cli
, mem_ctx
,
1685 cli
->srv_name_slash
,
1686 archi_table
[i
].long_archi
,
1689 archi_table
[i
].version
,
1692 if ( !W_ERROR_IS_OK(result
) )
1694 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1695 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1696 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1701 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1702 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1711 /****************************************************************************
1712 ****************************************************************************/
1714 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1715 TALLOC_CTX
*mem_ctx
,
1716 int argc
, const char **argv
)
1718 WERROR result
= WERR_OK
;
1722 /* parse the command arguments */
1724 printf ("Usage: %s <driver>\n", argv
[0]);
1728 /* delete the driver for all architectures */
1729 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1730 /* make the call to remove the driver */
1731 status
= rpccli_spoolss_DeletePrinterDriver(cli
, mem_ctx
,
1732 cli
->srv_name_slash
,
1733 archi_table
[i
].long_archi
,
1736 if (!NT_STATUS_IS_OK(status
)) {
1739 if ( !W_ERROR_IS_OK(result
) ) {
1740 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1741 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1742 argv
[1], archi_table
[i
].long_archi
,
1746 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1747 archi_table
[i
].long_archi
);
1754 /****************************************************************************
1755 ****************************************************************************/
1757 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1758 TALLOC_CTX
*mem_ctx
,
1759 int argc
, const char **argv
)
1763 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
1766 union spoolss_PrintProcessorDirectoryInfo info
;
1769 /* parse the command arguments */
1771 printf ("Usage: %s [environment]\n", argv
[0]);
1776 environment
= argv
[1];
1779 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1780 cli
->srv_name_slash
,
1788 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1790 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1792 status
= rpccli_spoolss_GetPrintProcessorDirectory(cli
, mem_ctx
,
1793 cli
->srv_name_slash
,
1803 if (W_ERROR_IS_OK(result
)) {
1804 printf("%s\n", info
.info1
.directory_name
);
1810 /****************************************************************************
1811 ****************************************************************************/
1813 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1814 int argc
, const char **argv
)
1819 const char *printername
;
1820 union spoolss_AddFormInfo info
;
1821 struct spoolss_AddFormInfo1 info1
;
1822 struct spoolss_AddFormInfo2 info2
;
1825 /* Parse the command arguments */
1827 if (argc
< 3 || argc
> 5) {
1828 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
1832 /* Get a printer handle */
1834 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1836 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1840 if (!W_ERROR_IS_OK(werror
))
1843 /* Dummy up some values for the form data */
1846 level
= atoi(argv
[3]);
1851 info1
.flags
= FORM_USER
;
1852 info1
.form_name
= argv
[2];
1853 info1
.size
.width
= 100;
1854 info1
.size
.height
= 100;
1855 info1
.area
.left
= 0;
1856 info1
.area
.top
= 10;
1857 info1
.area
.right
= 20;
1858 info1
.area
.bottom
= 30;
1860 info
.info1
= &info1
;
1864 info2
.flags
= FORM_USER
;
1865 info2
.form_name
= argv
[2];
1866 info2
.size
.width
= 100;
1867 info2
.size
.height
= 100;
1868 info2
.area
.left
= 0;
1869 info2
.area
.top
= 10;
1870 info2
.area
.right
= 20;
1871 info2
.area
.bottom
= 30;
1872 info2
.keyword
= argv
[2];
1873 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
1874 info2
.mui_dll
= NULL
;
1875 info2
.ressource_id
= 0;
1876 info2
.display_name
= argv
[2];
1879 info
.info2
= &info2
;
1887 status
= rpccli_spoolss_AddForm(cli
, mem_ctx
,
1894 if (is_valid_policy_hnd(&handle
))
1895 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1900 /****************************************************************************
1901 ****************************************************************************/
1903 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1904 int argc
, const char **argv
)
1909 const char *printername
;
1910 union spoolss_AddFormInfo info
;
1911 struct spoolss_AddFormInfo1 info1
;
1913 /* Parse the command arguments */
1916 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1920 /* Get a printer handle */
1922 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1924 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1926 SEC_FLAG_MAXIMUM_ALLOWED
,
1928 if (!W_ERROR_IS_OK(werror
))
1931 /* Dummy up some values for the form data */
1933 info1
.flags
= FORM_PRINTER
;
1934 info1
.size
.width
= 100;
1935 info1
.size
.height
= 100;
1936 info1
.area
.left
= 0;
1937 info1
.area
.top
= 1000;
1938 info1
.area
.right
= 2000;
1939 info1
.area
.bottom
= 3000;
1940 info1
.form_name
= argv
[2];
1942 info
.info1
= &info1
;
1946 status
= rpccli_spoolss_SetForm(cli
, mem_ctx
,
1954 if (is_valid_policy_hnd(&handle
))
1955 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
1960 /****************************************************************************
1961 ****************************************************************************/
1963 static const char *get_form_flag(int form_flag
)
1965 switch (form_flag
) {
1969 return "FORM_BUILTIN";
1971 return "FORM_PRINTER";
1977 /****************************************************************************
1978 ****************************************************************************/
1980 static void display_form_info1(struct spoolss_FormInfo1
*r
)
1983 "\tflag: %s (%d)\n" \
1984 "\twidth: %d, length: %d\n" \
1985 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1986 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
1987 r
->size
.width
, r
->size
.height
,
1988 r
->area
.left
, r
->area
.right
,
1989 r
->area
.top
, r
->area
.bottom
);
1992 /****************************************************************************
1993 ****************************************************************************/
1995 static void display_form_info2(struct spoolss_FormInfo2
*r
)
1998 "\tflag: %s (%d)\n" \
1999 "\twidth: %d, length: %d\n" \
2000 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2001 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2002 r
->size
.width
, r
->size
.height
,
2003 r
->area
.left
, r
->area
.right
,
2004 r
->area
.top
, r
->area
.bottom
);
2005 printf("\tkeyword: %s\n", r
->keyword
);
2006 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2007 printf("\tmui_dll: %s\n", r
->mui_dll
);
2008 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2009 printf("\tdisplay_name: %s\n", r
->display_name
);
2010 printf("\tlang_id: %d\n", r
->lang_id
);
2014 /****************************************************************************
2015 ****************************************************************************/
2017 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2018 int argc
, const char **argv
)
2023 const char *printername
;
2025 uint32_t offered
= 0;
2026 union spoolss_FormInfo info
;
2030 /* Parse the command arguments */
2032 if (argc
< 3 || argc
> 5) {
2033 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2037 /* Get a printer handle */
2039 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2041 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2043 SEC_FLAG_MAXIMUM_ALLOWED
,
2045 if (!W_ERROR_IS_OK(werror
))
2049 level
= atoi(argv
[3]);
2054 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2063 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2064 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2066 status
= rpccli_spoolss_GetForm(cli
, mem_ctx
,
2077 if (!NT_STATUS_IS_OK(status
)) {
2083 display_form_info1(&info
.info1
);
2086 display_form_info2(&info
.info2
);
2091 if (is_valid_policy_hnd(&handle
))
2092 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2097 /****************************************************************************
2098 ****************************************************************************/
2100 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2101 TALLOC_CTX
*mem_ctx
, int argc
,
2107 const char *printername
;
2109 /* Parse the command arguments */
2112 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2116 /* Get a printer handle */
2118 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2120 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2122 SEC_FLAG_MAXIMUM_ALLOWED
,
2124 if (!W_ERROR_IS_OK(werror
))
2127 /* Delete the form */
2129 status
= rpccli_spoolss_DeleteForm(cli
, mem_ctx
,
2133 if (!NT_STATUS_IS_OK(status
)) {
2134 return ntstatus_to_werror(status
);
2138 if (is_valid_policy_hnd(&handle
))
2139 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2144 /****************************************************************************
2145 ****************************************************************************/
2147 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2148 TALLOC_CTX
*mem_ctx
, int argc
,
2153 const char *printername
;
2154 uint32 num_forms
, level
= 1, i
;
2155 union spoolss_FormInfo
*forms
;
2157 /* Parse the command arguments */
2159 if (argc
< 2 || argc
> 4) {
2160 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2164 /* Get a printer handle */
2166 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2168 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2170 SEC_FLAG_MAXIMUM_ALLOWED
,
2172 if (!W_ERROR_IS_OK(werror
))
2176 level
= atoi(argv
[2]);
2179 /* Enumerate forms */
2181 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2188 if (!W_ERROR_IS_OK(werror
))
2191 /* Display output */
2193 for (i
= 0; i
< num_forms
; i
++) {
2196 display_form_info1(&forms
[i
].info1
);
2199 display_form_info2(&forms
[i
].info2
);
2205 if (is_valid_policy_hnd(&handle
))
2206 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &handle
, NULL
);
2211 /****************************************************************************
2212 ****************************************************************************/
2214 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2215 TALLOC_CTX
*mem_ctx
,
2216 int argc
, const char **argv
)
2219 const char *printername
;
2221 union spoolss_PrinterInfo info
;
2222 REGISTRY_VALUE value
;
2223 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2225 /* parse the command arguments */
2227 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2228 " <value> <data>\n",
2230 result
= WERR_INVALID_PARAM
;
2234 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2236 value
.type
= REG_NONE
;
2238 if (strequal(argv
[2], "string")) {
2239 value
.type
= REG_SZ
;
2242 if (strequal(argv
[2], "binary")) {
2243 value
.type
= REG_BINARY
;
2246 if (strequal(argv
[2], "dword")) {
2247 value
.type
= REG_DWORD
;
2250 if (strequal(argv
[2], "multistring")) {
2251 value
.type
= REG_MULTI_SZ
;
2254 if (value
.type
== REG_NONE
) {
2255 printf("Unknown data type: %s\n", argv
[2]);
2256 result
= WERR_INVALID_PARAM
;
2260 /* get a printer handle */
2262 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2264 SEC_FLAG_MAXIMUM_ALLOWED
,
2266 if (!W_ERROR_IS_OK(result
))
2269 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2274 if (!W_ERROR_IS_OK(result
))
2277 printf("%s\n", current_timestring(tmp_ctx
, True
));
2278 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2280 /* Set the printer data */
2282 fstrcpy(value
.valuename
, argv
[3]);
2284 switch (value
.type
) {
2287 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2288 value
.size
= data
.uni_str_len
* 2;
2290 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, data
.buffer
,
2293 value
.data_p
= NULL
;
2298 uint32 data
= strtoul(argv
[4], NULL
, 10);
2299 value
.size
= sizeof(data
);
2301 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, &data
,
2304 value
.data_p
= NULL
;
2309 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2310 value
.data_p
= data
.data
;
2311 value
.size
= data
.length
;
2314 case REG_MULTI_SZ
: {
2319 for (i
=4; i
<argc
; i
++) {
2320 if (strcmp(argv
[i
], "NULL") == 0) {
2323 len
+= strlen(argv
[i
])+1;
2327 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2328 if (value
.data_p
== NULL
) {
2329 result
= WERR_NOMEM
;
2333 p
= (char *)value
.data_p
;
2335 for (i
=4; i
<argc
; i
++) {
2336 size_t l
= (strlen(argv
[i
])+1)*2;
2337 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2341 SMB_ASSERT(len
== 0);
2345 printf("Unknown data type: %s\n", argv
[2]);
2346 result
= WERR_INVALID_PARAM
;
2350 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2352 if (!W_ERROR_IS_OK(result
)) {
2353 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2356 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2358 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2363 if (!W_ERROR_IS_OK(result
))
2366 printf("%s\n", current_timestring(tmp_ctx
, True
));
2367 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2371 TALLOC_FREE(tmp_ctx
);
2372 if (is_valid_policy_hnd(&pol
))
2373 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &pol
, NULL
);
2378 /****************************************************************************
2379 ****************************************************************************/
2381 static void display_job_info_1(JOB_INFO_1
*job
)
2383 fstring username
= "", document
= "", text_status
= "";
2385 rpcstr_pull(username
, job
->username
.buffer
,
2386 sizeof(username
), -1, STR_TERMINATE
);
2388 rpcstr_pull(document
, job
->document
.buffer
,
2389 sizeof(document
), -1, STR_TERMINATE
);
2391 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2392 sizeof(text_status
), -1, STR_TERMINATE
);
2394 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2395 username
, document
, text_status
, job
->pagesprinted
,
2399 /****************************************************************************
2400 ****************************************************************************/
2402 static void display_job_info_2(JOB_INFO_2
*job
)
2404 fstring username
= "", document
= "", text_status
= "";
2406 rpcstr_pull(username
, job
->username
.buffer
,
2407 sizeof(username
), -1, STR_TERMINATE
);
2409 rpcstr_pull(document
, job
->document
.buffer
,
2410 sizeof(document
), -1, STR_TERMINATE
);
2412 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2413 sizeof(text_status
), -1, STR_TERMINATE
);
2415 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job
->position
, job
->jobid
,
2416 username
, document
, text_status
, job
->pagesprinted
,
2417 job
->totalpages
, job
->size
);
2420 /****************************************************************************
2421 ****************************************************************************/
2423 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2425 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2426 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2430 /****************************************************************************
2431 ****************************************************************************/
2433 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2435 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2436 r
->position
, r
->job_id
,
2437 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2438 r
->total_pages
, r
->size
);
2441 /****************************************************************************
2442 ****************************************************************************/
2444 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2446 printf("jobid[%d], next_jobid[%d]\n",
2447 r
->job_id
, r
->next_job_id
);
2450 /****************************************************************************
2451 ****************************************************************************/
2453 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2455 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2456 r
->position
, r
->job_id
,
2457 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2458 r
->total_pages
, r
->size
, r
->size_high
);
2461 /****************************************************************************
2462 ****************************************************************************/
2464 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2465 TALLOC_CTX
*mem_ctx
, int argc
,
2469 uint32 level
= 1, num_jobs
, i
;
2470 const char *printername
;
2474 if (argc
< 2 || argc
> 3) {
2475 printf("Usage: %s printername [level]\n", argv
[0]);
2480 level
= atoi(argv
[2]);
2482 /* Open printer handle */
2484 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2486 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2488 SEC_FLAG_MAXIMUM_ALLOWED
,
2490 if (!W_ERROR_IS_OK(result
))
2493 /* Enumerate ports */
2495 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2498 if (!W_ERROR_IS_OK(result
))
2501 for (i
= 0; i
< num_jobs
; i
++) {
2504 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2507 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2510 d_printf("unknown info level %d\n", level
);
2516 if (is_valid_policy_hnd(&hnd
))
2517 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2522 /****************************************************************************
2523 ****************************************************************************/
2525 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2526 TALLOC_CTX
*mem_ctx
, int argc
,
2530 const char *printername
;
2531 struct policy_handle hnd
;
2534 union spoolss_JobInfo info
;
2536 if (argc
< 3 || argc
> 4) {
2537 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2541 job_id
= atoi(argv
[2]);
2544 level
= atoi(argv
[3]);
2547 /* Open printer handle */
2549 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2551 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2553 SEC_FLAG_MAXIMUM_ALLOWED
,
2555 if (!W_ERROR_IS_OK(result
)) {
2559 /* Enumerate ports */
2561 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2568 if (!W_ERROR_IS_OK(result
)) {
2574 display_job_info1(&info
.info1
);
2577 display_job_info2(&info
.info2
);
2580 display_job_info3(&info
.info3
);
2583 display_job_info4(&info
.info4
);
2586 d_printf("unknown info level %d\n", level
);
2591 if (is_valid_policy_hnd(&hnd
)) {
2592 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2599 /****************************************************************************
2600 ****************************************************************************/
2602 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2603 TALLOC_CTX
*mem_ctx
, int argc
,
2607 uint32 i
=0, val_needed
, data_needed
;
2608 const char *printername
;
2612 printf("Usage: %s printername\n", argv
[0]);
2616 /* Open printer handle */
2618 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2620 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2622 SEC_FLAG_MAXIMUM_ALLOWED
,
2624 if (!W_ERROR_IS_OK(result
))
2627 /* Enumerate data */
2629 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2630 &val_needed
, &data_needed
,
2632 while (W_ERROR_IS_OK(result
)) {
2633 REGISTRY_VALUE value
;
2634 result
= rpccli_spoolss_enumprinterdata(
2635 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2636 data_needed
, 0, 0, &value
);
2637 if (W_ERROR_IS_OK(result
))
2638 display_reg_value(value
);
2640 if (W_ERROR_V(result
) == ERRnomoreitems
)
2641 result
= W_ERROR(ERRsuccess
);
2644 if (is_valid_policy_hnd(&hnd
))
2645 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2650 /****************************************************************************
2651 ****************************************************************************/
2653 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2654 TALLOC_CTX
*mem_ctx
, int argc
,
2659 const char *printername
;
2660 const char *keyname
= NULL
;
2662 REGVAL_CTR
*ctr
= NULL
;
2665 printf("Usage: %s printername <keyname>\n", argv
[0]);
2671 /* Open printer handle */
2673 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2675 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2677 SEC_FLAG_MAXIMUM_ALLOWED
,
2679 if (!W_ERROR_IS_OK(result
))
2682 /* Enumerate subkeys */
2684 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2687 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2689 if (!W_ERROR_IS_OK(result
))
2692 for (i
=0; i
< ctr
->num_values
; i
++) {
2693 display_reg_value(*(ctr
->values
[i
]));
2699 if (is_valid_policy_hnd(&hnd
))
2700 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2705 /****************************************************************************
2706 ****************************************************************************/
2708 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2709 TALLOC_CTX
*mem_ctx
, int argc
,
2713 const char *printername
;
2714 const char *keyname
= NULL
;
2716 uint16
*keylist
= NULL
, *curkey
;
2718 if (argc
< 2 || argc
> 3) {
2719 printf("Usage: %s printername [keyname]\n", argv
[0]);
2728 /* Open printer handle */
2730 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2732 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2734 SEC_FLAG_MAXIMUM_ALLOWED
,
2736 if (!W_ERROR_IS_OK(result
))
2739 /* Enumerate subkeys */
2741 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2743 if (!W_ERROR_IS_OK(result
))
2747 while (*curkey
!= 0) {
2748 char *subkey
= NULL
;
2749 rpcstr_pull_talloc(mem_ctx
, &subkey
, curkey
, -1,
2754 printf("%s\n", subkey
);
2755 curkey
+= strlen(subkey
) + 1;
2762 if (is_valid_policy_hnd(&hnd
))
2763 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2768 /****************************************************************************
2769 ****************************************************************************/
2771 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2772 TALLOC_CTX
*mem_ctx
, int argc
,
2775 const char *printername
;
2776 const char *clientname
;
2780 struct spoolss_NotifyOption option
;
2783 printf("Usage: %s printername\n", argv
[0]);
2790 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2792 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2794 SEC_FLAG_MAXIMUM_ALLOWED
,
2796 if (!W_ERROR_IS_OK(result
)) {
2797 printf("Error opening %s\n", argv
[1]);
2801 /* Create spool options */
2806 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
2807 if (option
.types
== NULL
) {
2808 result
= WERR_NOMEM
;
2812 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
2813 option
.types
[0].count
= 1;
2814 option
.types
[0].fields
= talloc_array(mem_ctx
, enum spoolss_Field
, 1);
2815 if (option
.types
[0].fields
== NULL
) {
2816 result
= WERR_NOMEM
;
2819 option
.types
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2821 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
2822 option
.types
[1].count
= 1;
2823 option
.types
[1].fields
= talloc_array(mem_ctx
, enum spoolss_Field
, 1);
2824 if (option
.types
[1].fields
== NULL
) {
2825 result
= WERR_NOMEM
;
2828 option
.types
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2830 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", global_myname());
2832 result
= WERR_NOMEM
;
2838 status
= rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli
, mem_ctx
,
2846 if (!W_ERROR_IS_OK(result
)) {
2847 printf("Error rffpcnex %s\n", argv
[1]);
2852 if (is_valid_policy_hnd(&hnd
))
2853 rpccli_spoolss_ClosePrinter(cli
, mem_ctx
, &hnd
, NULL
);
2858 /****************************************************************************
2859 ****************************************************************************/
2861 static bool compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2862 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2864 union spoolss_PrinterInfo info1
, info2
;
2866 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2868 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
2869 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
2874 if ( !W_ERROR_IS_OK(werror
) ) {
2875 printf("failed (%s)\n", win_errstr(werror
));
2876 talloc_destroy(mem_ctx
);
2881 printf("Retrieving printer properties for %s...", cli2
->desthost
);
2882 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
2887 if ( !W_ERROR_IS_OK(werror
) ) {
2888 printf("failed (%s)\n", win_errstr(werror
));
2889 talloc_destroy(mem_ctx
);
2894 talloc_destroy(mem_ctx
);
2899 /****************************************************************************
2900 ****************************************************************************/
2902 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2903 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2905 union spoolss_PrinterInfo info1
, info2
;
2907 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2908 SEC_DESC
*sd1
, *sd2
;
2912 printf("Retrieving printer security for %s...", cli1
->desthost
);
2913 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
2918 if ( !W_ERROR_IS_OK(werror
) ) {
2919 printf("failed (%s)\n", win_errstr(werror
));
2925 printf("Retrieving printer security for %s...", cli2
->desthost
);
2926 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
2931 if ( !W_ERROR_IS_OK(werror
) ) {
2932 printf("failed (%s)\n", win_errstr(werror
));
2941 sd1
= info1
.info3
.secdesc
;
2942 sd2
= info2
.info3
.secdesc
;
2944 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2945 printf("NULL secdesc!\n");
2950 if (!sec_desc_equal( sd1
, sd2
) ) {
2951 printf("Security Descriptors *not* equal!\n");
2956 printf("Security descriptors match\n");
2959 talloc_destroy(mem_ctx
);
2964 /****************************************************************************
2965 ****************************************************************************/
2967 extern struct user_auth_info
*rpcclient_auth_info
;
2969 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2970 TALLOC_CTX
*mem_ctx
, int argc
,
2973 const char *printername
;
2974 char *printername_path
= NULL
;
2975 struct cli_state
*cli_server2
= NULL
;
2976 struct rpc_pipe_client
*cli2
= NULL
;
2977 POLICY_HND hPrinter1
, hPrinter2
;
2982 printf("Usage: %s <printer> <server>\n", argv
[0]);
2986 printername
= argv
[1];
2988 /* first get the connection to the remote server */
2990 nt_status
= cli_full_connection(&cli_server2
, global_myname(), argv
[2],
2993 get_cmdline_auth_info_username(rpcclient_auth_info
),
2995 get_cmdline_auth_info_password(rpcclient_auth_info
),
2996 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2997 get_cmdline_auth_info_signing_state(rpcclient_auth_info
), NULL
);
2999 if ( !NT_STATUS_IS_OK(nt_status
) )
3000 return WERR_GENERAL_FAILURE
;
3002 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &syntax_spoolss
,
3004 if (!NT_STATUS_IS_OK(nt_status
)) {
3005 printf("failed to open spoolss pipe on server %s (%s)\n",
3006 argv
[2], nt_errstr(nt_status
));
3007 return WERR_GENERAL_FAILURE
;
3010 /* now open up both printers */
3012 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3014 printf("Opening %s...", printername_path
);
3016 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3020 if ( !W_ERROR_IS_OK(werror
) ) {
3021 printf("failed (%s)\n", win_errstr(werror
));
3026 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3028 printf("Opening %s...", printername_path
);
3029 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3033 if ( !W_ERROR_IS_OK(werror
) ) {
3034 printf("failed (%s)\n", win_errstr(werror
));
3039 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3040 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3042 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3049 printf("Closing printers...");
3050 rpccli_spoolss_ClosePrinter( cli
, mem_ctx
, &hPrinter1
, NULL
);
3051 rpccli_spoolss_ClosePrinter( cli2
, mem_ctx
, &hPrinter2
, NULL
);
3054 /* close the second remote connection */
3056 cli_shutdown( cli_server2
);
3060 /* List of commands exported by this module */
3061 struct cmd_set spoolss_commands
[] = {
3065 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &syntax_spoolss
, NULL
, "Add a print driver", "" },
3066 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &syntax_spoolss
, NULL
, "Add a printer", "" },
3067 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &syntax_spoolss
, NULL
, "Delete a printer driver", "" },
3068 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &syntax_spoolss
, NULL
, "Delete a printer driver with files", "" },
3069 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &syntax_spoolss
, NULL
, "Enumerate printer data", "" },
3070 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &syntax_spoolss
, NULL
, "Enumerate printer data for a key", "" },
3071 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &syntax_spoolss
, NULL
, "Enumerate printer keys", "" },
3072 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &syntax_spoolss
, NULL
, "Enumerate print jobs", "" },
3073 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &syntax_spoolss
, NULL
, "Get print job", "" },
3074 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &syntax_spoolss
, NULL
, "Enumerate printer ports", "" },
3075 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &syntax_spoolss
, NULL
, "Enumerate installed printer drivers", "" },
3076 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &syntax_spoolss
, NULL
, "Enumerate printers", "" },
3077 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &syntax_spoolss
, NULL
, "Get print driver data", "" },
3078 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &syntax_spoolss
, NULL
, "Get printer driver data with keyname", ""},
3079 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &syntax_spoolss
, NULL
, "Get print driver information", "" },
3080 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &syntax_spoolss
, NULL
, "Get print driver upload directory", "" },
3081 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &syntax_spoolss
, NULL
, "Get printer info", "" },
3082 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &syntax_spoolss
, NULL
, "Open printer handle", "" },
3083 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &syntax_spoolss
, NULL
, "Set printer driver", "" },
3084 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &syntax_spoolss
, NULL
, "Get print processor directory", "" },
3085 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &syntax_spoolss
, NULL
, "Add form", "" },
3086 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &syntax_spoolss
, NULL
, "Set form", "" },
3087 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &syntax_spoolss
, NULL
, "Get form", "" },
3088 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &syntax_spoolss
, NULL
, "Delete form", "" },
3089 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &syntax_spoolss
, NULL
, "Enumerate forms", "" },
3090 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &syntax_spoolss
, NULL
, "Set printer comment", "" },
3091 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &syntax_spoolss
, NULL
, "Set printername", "" },
3092 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &syntax_spoolss
, NULL
, "Set REG_SZ printer data", "" },
3093 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &syntax_spoolss
, NULL
, "Rffpcnex test", "" },
3094 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &syntax_spoolss
, NULL
, "Printer comparison test", "" },