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;
516 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
518 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
525 if (W_ERROR_IS_OK(result))
526 printf("Success in setting comment.\n");
529 if (is_valid_policy_hnd(&pol))
530 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
535 /****************************************************************************
536 ****************************************************************************/
538 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
540 int argc, const char **argv)
545 uint32 info_level = 2;
546 union spoolss_PrinterInfo info;
547 const char *printername,
548 *new_printername = NULL;
549 struct spoolss_SetPrinterInfoCtr info_ctr;
550 struct spoolss_DevmodeContainer devmode_ctr;
551 struct sec_desc_buf secdesc_ctr;
553 ZERO_STRUCT(devmode_ctr);
554 ZERO_STRUCT(secdesc_ctr);
556 if (argc == 1 || argc > 3) {
557 printf("Usage: %s printername new_printername\n", argv[0]);
562 /* Open a printer handle */
564 new_printername = argv[2];
567 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
569 /* get a printer handle */
570 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
574 if (!W_ERROR_IS_OK(result))
577 /* Get printer info */
578 result = rpccli_spoolss_getprinter(cli, mem_ctx,
583 if (!W_ERROR_IS_OK(result))
586 /* Modify the printername. */
587 info.info2.printername = new_printername;
588 info.info2.devmode = NULL;
589 info.info2.secdesc = NULL;
591 info_ctr.level = info_level;
592 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
594 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
601 if (W_ERROR_IS_OK(result))
602 printf("Success in setting printername.\n");
605 if (is_valid_policy_hnd(&pol))
606 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
611 /****************************************************************************
612 ****************************************************************************/
614 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
616 int argc, const char **argv)
620 uint32 info_level = 1;
621 const char *printername;
622 union spoolss_PrinterInfo info;
624 if (argc == 1 || argc > 3) {
625 printf("Usage: %s <printername> [level]\n", argv[0]);
629 /* Open a printer handle */
631 info_level = atoi(argv[2]);
634 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
636 /* get a printer handle */
638 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
640 SEC_FLAG_MAXIMUM_ALLOWED,
642 if (!W_ERROR_IS_OK(result))
645 /* Get printer info */
647 result = rpccli_spoolss_getprinter(cli, mem_ctx,
652 if (!W_ERROR_IS_OK(result))
655 /* Display printer info */
656 switch (info_level) {
659 display_print_info_0(ctr.printers_0);
662 display_print_info_1(ctr.printers_1);
665 display_print_info_2(ctr.printers_2);
668 display_print_info_3(ctr.printers_3);
672 display_print_info7(&info.info7);
675 printf("unknown info level %d\n", info_level);
679 if (is_valid_policy_hnd(&pol))
680 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
685 /****************************************************************************
686 ****************************************************************************/
688 static void display_reg_value(REGISTRY_VALUE value)
694 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
695 *((uint32 *) value.data_p));
698 rpcstr_pull_talloc(talloc_tos(),
703 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
706 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
708 printf("%s: REG_BINARY:", value.valuename);
710 for (i=0; i<len; i++) {
711 if (hex[i] == '\0') {
724 uint32 i, num_values;
727 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
728 value.size, &num_values,
730 d_printf("reg_pull_multi_sz failed\n");
734 for (i=0; i<num_values; i++) {
735 d_printf("%s\n", values[i]);
741 printf("%s: unknown type %d\n", value.valuename, value.type);
746 /****************************************************************************
747 ****************************************************************************/
749 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
751 int argc, const char **argv)
756 const char *valuename;
757 REGISTRY_VALUE value;
760 printf("Usage: %s <printername> <valuename>\n", argv[0]);
761 printf("<printername> of . queries print server\n");
766 /* Open a printer handle */
768 if (strncmp(argv[1], ".", sizeof(".")) == 0)
769 fstrcpy(printername, cli->srv_name_slash);
771 slprintf(printername, sizeof(printername)-1, "%s\\%s",
772 cli->srv_name_slash, argv[1]);
774 /* get a printer handle */
776 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
778 SEC_FLAG_MAXIMUM_ALLOWED,
780 if (!W_ERROR_IS_OK(result))
783 /* Get printer info */
785 result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
787 if (!W_ERROR_IS_OK(result))
790 /* Display printer data */
792 fstrcpy(value.valuename, valuename);
793 display_reg_value(value);
797 if (is_valid_policy_hnd(&pol))
798 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
803 /****************************************************************************
804 ****************************************************************************/
806 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
808 int argc, const char **argv)
814 const char *valuename, *keyname;
815 REGISTRY_VALUE value;
818 uint8_t *buffer = NULL;
819 uint32_t offered = 0;
823 printf("Usage: %s <printername> <keyname> <valuename>\n",
825 printf("<printername> of . queries print server\n");
831 /* Open a printer handle */
833 if (strncmp(argv[1], ".", sizeof(".")) == 0)
834 fstrcpy(printername, cli->srv_name_slash);
836 slprintf(printername, sizeof(printername)-1, "%s\\%s",
837 cli->srv_name_slash, argv[1]);
839 /* get a printer handle */
841 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
843 SEC_FLAG_MAXIMUM_ALLOWED,
845 if (!W_ERROR_IS_OK(result))
848 /* Get printer info */
850 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
859 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
861 buffer = talloc_array(mem_ctx, uint8_t, needed);
862 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
873 if (!NT_STATUS_IS_OK(status)) {
877 if (!W_ERROR_IS_OK(result)) {
882 if (!W_ERROR_IS_OK(result))
885 /* Display printer data */
887 fstrcpy(value.valuename, valuename);
890 value.data_p = buffer;
892 display_reg_value(value);
895 if (is_valid_policy_hnd(&pol))
896 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
901 /****************************************************************************
902 ****************************************************************************/
904 static void display_print_driver_1(DRIVER_INFO_1 *i1)
910 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
912 printf ("Printer Driver Info 1:\n");
913 printf ("\tDriver Name: [%s]\n\n", name);
918 /****************************************************************************
919 ****************************************************************************/
921 static void display_print_driver_2(DRIVER_INFO_2 *i1)
924 fstring architecture;
931 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
932 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
933 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
934 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
935 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
937 printf ("Printer Driver Info 2:\n");
938 printf ("\tVersion: [%x]\n", i1->version);
939 printf ("\tDriver Name: [%s]\n", name);
940 printf ("\tArchitecture: [%s]\n", architecture);
941 printf ("\tDriver Path: [%s]\n", driverpath);
942 printf ("\tDatafile: [%s]\n", datafile);
943 printf ("\tConfigfile: [%s]\n\n", configfile);
948 /****************************************************************************
949 ****************************************************************************/
951 static void display_print_driver_3(DRIVER_INFO_3 *i1)
954 fstring architecture = "";
955 fstring driverpath = "";
956 fstring datafile = "";
957 fstring configfile = "";
958 fstring helpfile = "";
959 fstring dependentfiles = "";
960 fstring monitorname = "";
961 fstring defaultdatatype = "";
969 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
970 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
971 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
972 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
973 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
974 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
975 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
976 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
978 printf ("Printer Driver Info 3:\n");
979 printf ("\tVersion: [%x]\n", i1->version);
980 printf ("\tDriver Name: [%s]\n",name);
981 printf ("\tArchitecture: [%s]\n", architecture);
982 printf ("\tDriver Path: [%s]\n", driverpath);
983 printf ("\tDatafile: [%s]\n", datafile);
984 printf ("\tConfigfile: [%s]\n", configfile);
985 printf ("\tHelpfile: [%s]\n\n", helpfile);
989 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
991 length+=strlen(dependentfiles)+1;
993 if (strlen(dependentfiles) > 0)
995 printf ("\tDependentfiles: [%s]\n", dependentfiles);
1005 printf ("\tMonitorname: [%s]\n", monitorname);
1006 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
1011 /****************************************************************************
1012 ****************************************************************************/
1014 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
1020 printf("Printer Driver Info 1:\n");
1021 printf("\tDriver Name: [%s]\n\n", r->driver_name);
1024 /****************************************************************************
1025 ****************************************************************************/
1027 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
1033 printf("Printer Driver Info 2:\n");
1034 printf("\tVersion: [%x]\n", r->version);
1035 printf("\tDriver Name: [%s]\n", r->driver_name);
1036 printf("\tArchitecture: [%s]\n", r->architecture);
1037 printf("\tDriver Path: [%s]\n", r->driver_path);
1038 printf("\tDatafile: [%s]\n", r->data_file);
1039 printf("\tConfigfile: [%s]\n\n", r->config_file);
1042 /****************************************************************************
1043 ****************************************************************************/
1045 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1053 printf("Printer Driver Info 3:\n");
1054 printf("\tVersion: [%x]\n", r->version);
1055 printf("\tDriver Name: [%s]\n", r->driver_name);
1056 printf("\tArchitecture: [%s]\n", r->architecture);
1057 printf("\tDriver Path: [%s]\n", r->driver_path);
1058 printf("\tDatafile: [%s]\n", r->data_file);
1059 printf("\tConfigfile: [%s]\n\n", r->config_file);
1060 printf("\tHelpfile: [%s]\n\n", r->help_file);
1062 for (i=0; r->dependent_files[i] != NULL; i++) {
1063 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1068 printf("\tMonitorname: [%s]\n", r->monitor_name);
1069 printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
1073 /****************************************************************************
1074 ****************************************************************************/
1076 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1077 TALLOC_CTX *mem_ctx,
1078 int argc, const char **argv)
1082 uint32 info_level = 3;
1083 const char *printername;
1085 bool success = False;
1086 union spoolss_DriverInfo info;
1087 uint32_t server_major_version;
1088 uint32_t server_minor_version;
1090 if ((argc == 1) || (argc > 3))
1092 printf("Usage: %s <printername> [level]\n", argv[0]);
1096 /* get the arguments need to open the printer handle */
1098 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1101 info_level = atoi(argv[2]);
1103 /* Open a printer handle */
1105 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1109 if (!W_ERROR_IS_OK(werror)) {
1110 printf("Error opening printer handle for %s!\n", printername);
1114 /* loop through and print driver info level for each architecture */
1116 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1118 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1120 archi_table[i].long_archi,
1123 archi_table[i].version,
1126 &server_major_version,
1127 &server_minor_version);
1128 if (!W_ERROR_IS_OK(werror))
1131 /* need at least one success */
1135 printf ("\n[%s]\n", archi_table[i].long_archi);
1137 switch (info_level) {
1139 display_print_driver1(&info.info1);
1142 display_print_driver2(&info.info2);
1145 display_print_driver3(&info.info3);
1148 printf("unknown info level %d\n", info_level);
1155 if (is_valid_policy_hnd(&pol))
1156 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1164 /****************************************************************************
1165 ****************************************************************************/
1167 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1168 TALLOC_CTX *mem_ctx,
1169 int argc, const char **argv)
1171 WERROR werror = WERR_OK;
1172 uint32 info_level = 1;
1173 PRINTER_DRIVER_CTR ctr;
1178 printf("Usage: enumdrivers [level]\n");
1183 info_level = atoi(argv[1]);
1186 /* loop through and print driver info level for each architecture */
1187 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1188 /* check to see if we already asked for this architecture string */
1190 if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
1193 werror = rpccli_spoolss_enumprinterdrivers(
1194 cli, mem_ctx, info_level,
1195 archi_table[i].long_archi, &returned, &ctr);
1197 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1198 printf ("Server does not support environment [%s]\n",
1199 archi_table[i].long_archi);
1207 if (!W_ERROR_IS_OK(werror)) {
1208 printf ("Error getting driver for environment [%s] - %d\n",
1209 archi_table[i].long_archi, W_ERROR_V(werror));
1213 printf ("\n[%s]\n", archi_table[i].long_archi);
1218 for (j=0; j < returned; j++) {
1219 display_print_driver_1 (&ctr.info1[j]);
1223 for (j=0; j < returned; j++) {
1224 display_print_driver_2 (&ctr.info2[j]);
1228 for (j=0; j < returned; j++) {
1229 display_print_driver_3 (&ctr.info3[j]);
1233 printf("unknown info level %d\n", info_level);
1234 return WERR_UNKNOWN_LEVEL;
1241 /****************************************************************************
1242 ****************************************************************************/
1244 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1246 printf("\tDirectory Name:[%s]\n", r->directory_name);
1249 /****************************************************************************
1250 ****************************************************************************/
1252 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1253 TALLOC_CTX *mem_ctx,
1254 int argc, const char **argv)
1258 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1261 union spoolss_DriverDirectoryInfo info;
1265 printf("Usage: %s [environment]\n", argv[0]);
1269 /* Get the arguments need to open the printer handle */
1275 /* Get the directory. Only use Info level 1 */
1277 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1278 cli->srv_name_slash,
1286 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1288 buffer = data_blob_talloc_zero(mem_ctx, needed);
1290 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1291 cli->srv_name_slash,
1301 if (W_ERROR_IS_OK(result)) {
1302 display_printdriverdir_1(&info.info1);
1308 /****************************************************************************
1309 ****************************************************************************/
1311 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1312 struct spoolss_AddDriverInfo3 *info,
1318 for (i=0; archi_table[i].long_archi != NULL; i++)
1320 if (strcmp(arch, archi_table[i].short_archi) == 0)
1322 info->version = archi_table[i].version;
1323 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1328 if (archi_table[i].long_archi == NULL)
1330 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1337 /**************************************************************************
1338 wrapper for strtok to get the next parameter from a delimited list.
1339 Needed to handle the empty parameter string denoted by "NULL"
1340 *************************************************************************/
1342 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1343 const char *delim, const char **dest,
1348 /* get the next token */
1349 ptr = strtok_r(str, delim, saveptr);
1351 /* a string of 'NULL' is used to represent an empty
1352 parameter because two consecutive delimiters
1353 will not return an empty string. See man strtok(3)
1355 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1360 *dest = talloc_strdup(mem_ctx, ptr);
1366 /********************************************************************************
1367 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1368 string in the form of
1369 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1370 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1371 <Default Data Type>:<Comma Separated list of Files>
1372 *******************************************************************************/
1374 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1379 char *saveptr = NULL;
1380 struct spoolss_StringArray *deps;
1381 const char **file_array = NULL;
1384 /* fill in the UNISTR fields */
1385 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1386 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1387 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1388 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1389 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1390 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1391 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1393 /* <Comma Separated List of Dependent Files> */
1394 /* save the beginning of the string */
1395 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1398 /* begin to strip out each filename */
1399 str = strtok_r(str, ",", &saveptr);
1401 /* no dependent files, we are done */
1406 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1411 while (str != NULL) {
1412 add_string_to_array(deps, str, &file_array, &count);
1413 str = strtok_r(NULL, ",", &saveptr);
1416 deps->string = talloc_zero_array(deps, const char *, count + 1);
1417 if (!deps->string) {
1421 for (i=0; i < count; i++) {
1422 deps->string[i] = file_array[i];
1425 r->dependent_files = deps;
1430 /****************************************************************************
1431 ****************************************************************************/
1433 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1434 TALLOC_CTX *mem_ctx,
1435 int argc, const char **argv)
1440 struct spoolss_AddDriverInfoCtr info_ctr;
1441 struct spoolss_AddDriverInfo3 info3;
1445 /* parse the command arguments */
1446 if (argc != 3 && argc != 4)
1448 printf ("Usage: %s <Environment> \\\n", argv[0]);
1449 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1450 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1451 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1452 printf ("\t[version]\n");
1457 /* Fill in the spoolss_AddDriverInfo3 struct */
1460 arch = cmd_spoolss_get_short_archi(argv[1]);
1462 printf ("Error Unknown architechture [%s]\n", argv[1]);
1463 return WERR_INVALID_PARAM;
1466 set_drv_info_3_env(mem_ctx, &info3, arch);
1468 driver_args = talloc_strdup( mem_ctx, argv[2] );
1469 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1471 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1472 return WERR_INVALID_PARAM;
1475 /* if printer driver version specified, override the default version
1476 * used by the architecture. This allows installation of Windows
1477 * 2000 (version 3) printer drivers. */
1480 info3.version = atoi(argv[3]);
1484 info_ctr.level = level;
1485 info_ctr.info.info3 = &info3;
1487 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1488 cli->srv_name_slash,
1491 if (!NT_STATUS_IS_OK(status)) {
1492 return ntstatus_to_werror(status);
1494 if (W_ERROR_IS_OK(result)) {
1495 printf ("Printer Driver %s successfully installed.\n",
1503 /****************************************************************************
1504 ****************************************************************************/
1506 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1507 TALLOC_CTX *mem_ctx,
1508 int argc, const char **argv)
1511 struct spoolss_SetPrinterInfoCtr info_ctr;
1512 struct spoolss_SetPrinterInfo2 info2;
1514 /* parse the command arguments */
1517 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1521 /* Fill in the DRIVER_INFO_2 struct */
1524 info2.printername = argv[1];
1525 info2.drivername = argv[3];
1526 info2.sharename = argv[2];
1527 info2.portname = argv[4];
1528 info2.comment = "Created by rpcclient";
1529 info2.printprocessor = "winprint";
1530 info2.datatype = "RAW";
1531 info2.devmode = NULL;
1532 info2.secdesc = NULL;
1533 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1535 info2.defaultpriority = 0;
1536 info2.starttime = 0;
1537 info2.untiltime = 0;
1539 /* These three fields must not be used by AddPrinter()
1540 as defined in the MS Platform SDK documentation..
1544 info2.averageppm = 0;
1548 info_ctr.info.info2 = &info2;
1550 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1552 if (W_ERROR_IS_OK(result))
1553 printf ("Printer %s successfully installed.\n", argv[1]);
1558 /****************************************************************************
1559 ****************************************************************************/
1561 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1562 TALLOC_CTX *mem_ctx,
1563 int argc, const char **argv)
1569 const char *printername;
1570 union spoolss_PrinterInfo info;
1571 struct spoolss_SetPrinterInfoCtr info_ctr;
1572 struct spoolss_DevmodeContainer devmode_ctr;
1573 struct sec_desc_buf secdesc_ctr;
1575 ZERO_STRUCT(devmode_ctr);
1576 ZERO_STRUCT(secdesc_ctr);
1578 /* parse the command arguments */
1581 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1585 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1587 /* Get a printer handle */
1589 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1593 if (!W_ERROR_IS_OK(result))
1596 /* Get printer info */
1598 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1603 if (!W_ERROR_IS_OK(result)) {
1604 printf ("Unable to retrieve printer information!\n");
1608 /* Set the printer driver */
1610 info.info2.drivername = argv[2];
1612 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
1614 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1621 if (!W_ERROR_IS_OK(result)) {
1622 printf("SetPrinter call failed!\n");
1626 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1631 if (is_valid_policy_hnd(&pol))
1632 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1638 /****************************************************************************
1639 ****************************************************************************/
1641 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1642 TALLOC_CTX *mem_ctx,
1643 int argc, const char **argv)
1645 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1651 const char *arch = NULL;
1652 uint32_t delete_flags = 0;
1654 /* parse the command arguments */
1655 if (argc < 2 || argc > 4) {
1656 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1663 vers = atoi (argv[3]);
1666 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1669 /* delete the driver for all architectures */
1670 for (i=0; archi_table[i].long_archi; i++) {
1672 if (arch && !strequal( archi_table[i].long_archi, arch))
1675 if (vers >= 0 && archi_table[i].version != vers)
1678 /* make the call to remove the driver */
1679 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1680 cli->srv_name_slash,
1681 archi_table[i].long_archi,
1684 archi_table[i].version,
1687 if ( !W_ERROR_IS_OK(result) )
1689 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1690 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1691 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1696 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1697 archi_table[i].long_archi, archi_table[i].version);
1706 /****************************************************************************
1707 ****************************************************************************/
1709 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1710 TALLOC_CTX *mem_ctx,
1711 int argc, const char **argv)
1713 WERROR result = WERR_OK;
1717 /* parse the command arguments */
1719 printf ("Usage: %s <driver>\n", argv[0]);
1723 /* delete the driver for all architectures */
1724 for (i=0; archi_table[i].long_archi; i++) {
1725 /* make the call to remove the driver */
1726 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1727 cli->srv_name_slash,
1728 archi_table[i].long_archi,
1731 if (!NT_STATUS_IS_OK(status)) {
1734 if ( !W_ERROR_IS_OK(result) ) {
1735 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1736 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1737 argv[1], archi_table[i].long_archi,
1741 printf ("Driver %s removed for arch [%s].\n", argv[1],
1742 archi_table[i].long_archi);
1749 /****************************************************************************
1750 ****************************************************************************/
1752 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1753 TALLOC_CTX *mem_ctx,
1754 int argc, const char **argv)
1758 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1761 union spoolss_PrintProcessorDirectoryInfo info;
1764 /* parse the command arguments */
1766 printf ("Usage: %s [environment]\n", argv[0]);
1771 environment = argv[1];
1774 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1775 cli->srv_name_slash,
1783 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1785 buffer = data_blob_talloc_zero(mem_ctx, needed);
1787 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1788 cli->srv_name_slash,
1798 if (W_ERROR_IS_OK(result)) {
1799 printf("%s\n", info.info1.directory_name);
1805 /****************************************************************************
1806 ****************************************************************************/
1808 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1809 int argc, const char **argv)
1814 const char *printername;
1815 union spoolss_AddFormInfo info;
1816 struct spoolss_AddFormInfo1 info1;
1817 struct spoolss_AddFormInfo2 info2;
1820 /* Parse the command arguments */
1822 if (argc < 3 || argc > 5) {
1823 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
1827 /* Get a printer handle */
1829 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1831 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1835 if (!W_ERROR_IS_OK(werror))
1838 /* Dummy up some values for the form data */
1841 level = atoi(argv[3]);
1846 info1.flags = FORM_USER;
1847 info1.form_name = argv[2];
1848 info1.size.width = 100;
1849 info1.size.height = 100;
1850 info1.area.left = 0;
1851 info1.area.top = 10;
1852 info1.area.right = 20;
1853 info1.area.bottom = 30;
1855 info.info1 = &info1;
1859 info2.flags = FORM_USER;
1860 info2.form_name = argv[2];
1861 info2.size.width = 100;
1862 info2.size.height = 100;
1863 info2.area.left = 0;
1864 info2.area.top = 10;
1865 info2.area.right = 20;
1866 info2.area.bottom = 30;
1867 info2.keyword = argv[2];
1868 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
1869 info2.mui_dll = NULL;
1870 info2.ressource_id = 0;
1871 info2.display_name = argv[2];
1874 info.info2 = &info2;
1882 status = rpccli_spoolss_AddForm(cli, mem_ctx,
1889 if (is_valid_policy_hnd(&handle))
1890 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1895 /****************************************************************************
1896 ****************************************************************************/
1898 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1899 int argc, const char **argv)
1904 const char *printername;
1905 union spoolss_AddFormInfo info;
1906 struct spoolss_AddFormInfo1 info1;
1908 /* Parse the command arguments */
1911 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1915 /* Get a printer handle */
1917 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1919 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1921 SEC_FLAG_MAXIMUM_ALLOWED,
1923 if (!W_ERROR_IS_OK(werror))
1926 /* Dummy up some values for the form data */
1928 info1.flags = FORM_PRINTER;
1929 info1.size.width = 100;
1930 info1.size.height = 100;
1931 info1.area.left = 0;
1932 info1.area.top = 1000;
1933 info1.area.right = 2000;
1934 info1.area.bottom = 3000;
1935 info1.form_name = argv[2];
1937 info.info1 = &info1;
1941 status = rpccli_spoolss_SetForm(cli, mem_ctx,
1949 if (is_valid_policy_hnd(&handle))
1950 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1955 /****************************************************************************
1956 ****************************************************************************/
1958 static const char *get_form_flag(int form_flag)
1960 switch (form_flag) {
1964 return "FORM_BUILTIN";
1966 return "FORM_PRINTER";
1972 /****************************************************************************
1973 ****************************************************************************/
1975 static void display_form(FORM_1 *form)
1977 fstring form_name = "";
1979 if (form->name.buffer)
1980 rpcstr_pull(form_name, form->name.buffer,
1981 sizeof(form_name), -1, STR_TERMINATE);
1984 "\tflag: %s (%d)\n" \
1985 "\twidth: %d, length: %d\n" \
1986 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1987 form_name, get_form_flag(form->flag), form->flag,
1988 form->width, form->length,
1989 form->left, form->right,
1990 form->top, form->bottom);
1993 /****************************************************************************
1994 ****************************************************************************/
1996 static void display_form_info1(struct spoolss_FormInfo1 *r)
1999 "\tflag: %s (%d)\n" \
2000 "\twidth: %d, length: %d\n" \
2001 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2002 r->form_name, get_form_flag(r->flags), r->flags,
2003 r->size.width, r->size.height,
2004 r->area.left, r->area.right,
2005 r->area.top, r->area.bottom);
2008 /****************************************************************************
2009 ****************************************************************************/
2011 static void display_form_info2(struct spoolss_FormInfo2 *r)
2014 "\tflag: %s (%d)\n" \
2015 "\twidth: %d, length: %d\n" \
2016 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2017 r->form_name, get_form_flag(r->flags), r->flags,
2018 r->size.width, r->size.height,
2019 r->area.left, r->area.right,
2020 r->area.top, r->area.bottom);
2021 printf("\tkeyword: %s\n", r->keyword);
2022 printf("\tstring_type: 0x%08x\n", r->string_type);
2023 printf("\tmui_dll: %s\n", r->mui_dll);
2024 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2025 printf("\tdisplay_name: %s\n", r->display_name);
2026 printf("\tlang_id: %d\n", r->lang_id);
2030 /****************************************************************************
2031 ****************************************************************************/
2033 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2034 int argc, const char **argv)
2039 const char *printername;
2041 uint32_t offered = 0;
2042 union spoolss_FormInfo info;
2046 /* Parse the command arguments */
2048 if (argc < 3 || argc > 5) {
2049 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2053 /* Get a printer handle */
2055 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2057 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2059 SEC_FLAG_MAXIMUM_ALLOWED,
2061 if (!W_ERROR_IS_OK(werror))
2065 level = atoi(argv[3]);
2070 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2079 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2080 buffer = data_blob_talloc_zero(mem_ctx, needed);
2082 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2093 if (!NT_STATUS_IS_OK(status)) {
2099 display_form_info1(&info.info1);
2102 display_form_info2(&info.info2);
2107 if (is_valid_policy_hnd(&handle))
2108 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2113 /****************************************************************************
2114 ****************************************************************************/
2116 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2117 TALLOC_CTX *mem_ctx, int argc,
2123 const char *printername;
2125 /* Parse the command arguments */
2128 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2132 /* Get a printer handle */
2134 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2136 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2138 SEC_FLAG_MAXIMUM_ALLOWED,
2140 if (!W_ERROR_IS_OK(werror))
2143 /* Delete the form */
2145 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2149 if (!NT_STATUS_IS_OK(status)) {
2150 return ntstatus_to_werror(status);
2154 if (is_valid_policy_hnd(&handle))
2155 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2160 /****************************************************************************
2161 ****************************************************************************/
2163 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2164 TALLOC_CTX *mem_ctx, int argc,
2169 const char *printername;
2170 uint32 num_forms, level = 1, i;
2173 /* Parse the command arguments */
2176 printf ("Usage: %s <printer>\n", argv[0]);
2180 /* Get a printer handle */
2182 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2184 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2186 SEC_FLAG_MAXIMUM_ALLOWED,
2188 if (!W_ERROR_IS_OK(werror))
2191 /* Enumerate forms */
2193 werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
2195 if (!W_ERROR_IS_OK(werror))
2198 /* Display output */
2200 for (i = 0; i < num_forms; i++) {
2202 display_form(&forms[i]);
2207 if (is_valid_policy_hnd(&handle))
2208 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2213 /****************************************************************************
2214 ****************************************************************************/
2216 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2217 TALLOC_CTX *mem_ctx,
2218 int argc, const char **argv)
2221 const char *printername;
2223 union spoolss_PrinterInfo info;
2224 REGISTRY_VALUE value;
2225 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2227 /* parse the command arguments */
2229 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2230 " <value> <data>\n",
2232 result = WERR_INVALID_PARAM;
2236 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2238 value.type = REG_NONE;
2240 if (strequal(argv[2], "string")) {
2241 value.type = REG_SZ;
2244 if (strequal(argv[2], "binary")) {
2245 value.type = REG_BINARY;
2248 if (strequal(argv[2], "dword")) {
2249 value.type = REG_DWORD;
2252 if (strequal(argv[2], "multistring")) {
2253 value.type = REG_MULTI_SZ;
2256 if (value.type == REG_NONE) {
2257 printf("Unknown data type: %s\n", argv[2]);
2258 result = WERR_INVALID_PARAM;
2262 /* get a printer handle */
2264 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2266 SEC_FLAG_MAXIMUM_ALLOWED,
2268 if (!W_ERROR_IS_OK(result))
2271 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2276 if (!W_ERROR_IS_OK(result))
2279 printf("%s\n", current_timestring(tmp_ctx, True));
2280 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2282 /* Set the printer data */
2284 fstrcpy(value.valuename, argv[3]);
2286 switch (value.type) {
2289 init_unistr2(&data, argv[4], UNI_STR_TERMINATE);
2290 value.size = data.uni_str_len * 2;
2292 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer,
2295 value.data_p = NULL;
2300 uint32 data = strtoul(argv[4], NULL, 10);
2301 value.size = sizeof(data);
2303 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data,
2306 value.data_p = NULL;
2311 DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]);
2312 value.data_p = data.data;
2313 value.size = data.length;
2316 case REG_MULTI_SZ: {
2321 for (i=4; i<argc; i++) {
2322 if (strcmp(argv[i], "NULL") == 0) {
2325 len += strlen(argv[i])+1;
2329 value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size);
2330 if (value.data_p == NULL) {
2331 result = WERR_NOMEM;
2335 p = (char *)value.data_p;
2337 for (i=4; i<argc; i++) {
2338 size_t l = (strlen(argv[i])+1)*2;
2339 rpcstr_push(p, argv[i], len, STR_TERMINATE);
2343 SMB_ASSERT(len == 0);
2347 printf("Unknown data type: %s\n", argv[2]);
2348 result = WERR_INVALID_PARAM;
2352 result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
2354 if (!W_ERROR_IS_OK(result)) {
2355 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2358 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2360 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2365 if (!W_ERROR_IS_OK(result))
2368 printf("%s\n", current_timestring(tmp_ctx, True));
2369 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2373 TALLOC_FREE(tmp_ctx);
2374 if (is_valid_policy_hnd(&pol))
2375 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2380 /****************************************************************************
2381 ****************************************************************************/
2383 static void display_job_info_1(JOB_INFO_1 *job)
2385 fstring username = "", document = "", text_status = "";
2387 rpcstr_pull(username, job->username.buffer,
2388 sizeof(username), -1, STR_TERMINATE);
2390 rpcstr_pull(document, job->document.buffer,
2391 sizeof(document), -1, STR_TERMINATE);
2393 rpcstr_pull(text_status, job->text_status.buffer,
2394 sizeof(text_status), -1, STR_TERMINATE);
2396 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
2397 username, document, text_status, job->pagesprinted,
2401 /****************************************************************************
2402 ****************************************************************************/
2404 static void display_job_info_2(JOB_INFO_2 *job)
2406 fstring username = "", document = "", text_status = "";
2408 rpcstr_pull(username, job->username.buffer,
2409 sizeof(username), -1, STR_TERMINATE);
2411 rpcstr_pull(document, job->document.buffer,
2412 sizeof(document), -1, STR_TERMINATE);
2414 rpcstr_pull(text_status, job->text_status.buffer,
2415 sizeof(text_status), -1, STR_TERMINATE);
2417 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
2418 username, document, text_status, job->pagesprinted,
2419 job->totalpages, job->size);
2422 /****************************************************************************
2423 ****************************************************************************/
2425 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2426 TALLOC_CTX *mem_ctx, int argc,
2430 uint32 level = 1, num_jobs, i;
2431 const char *printername;
2435 if (argc < 2 || argc > 3) {
2436 printf("Usage: %s printername [level]\n", argv[0]);
2441 level = atoi(argv[2]);
2443 /* Open printer handle */
2445 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2447 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2449 SEC_FLAG_MAXIMUM_ALLOWED,
2451 if (!W_ERROR_IS_OK(result))
2454 /* Enumerate ports */
2456 result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
2459 if (!W_ERROR_IS_OK(result))
2462 for (i = 0; i < num_jobs; i++) {
2465 display_job_info_1(&ctr.job.job_info_1[i]);
2468 display_job_info_2(&ctr.job.job_info_2[i]);
2471 d_printf("unknown info level %d\n", level);
2477 if (is_valid_policy_hnd(&hnd))
2478 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2483 /****************************************************************************
2484 ****************************************************************************/
2486 static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
2487 TALLOC_CTX *mem_ctx, int argc,
2491 uint32 i=0, val_needed, data_needed;
2492 const char *printername;
2496 printf("Usage: %s printername\n", argv[0]);
2500 /* Open printer handle */
2502 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2504 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2506 SEC_FLAG_MAXIMUM_ALLOWED,
2508 if (!W_ERROR_IS_OK(result))
2511 /* Enumerate data */
2513 result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2514 &val_needed, &data_needed,
2516 while (W_ERROR_IS_OK(result)) {
2517 REGISTRY_VALUE value;
2518 result = rpccli_spoolss_enumprinterdata(
2519 cli, mem_ctx, &hnd, i++, val_needed,
2520 data_needed, 0, 0, &value);
2521 if (W_ERROR_IS_OK(result))
2522 display_reg_value(value);
2524 if (W_ERROR_V(result) == ERRnomoreitems)
2525 result = W_ERROR(ERRsuccess);
2528 if (is_valid_policy_hnd(&hnd))
2529 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2534 /****************************************************************************
2535 ****************************************************************************/
2537 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2538 TALLOC_CTX *mem_ctx, int argc,
2543 const char *printername;
2544 const char *keyname = NULL;
2546 REGVAL_CTR *ctr = NULL;
2549 printf("Usage: %s printername <keyname>\n", argv[0]);
2555 /* Open printer handle */
2557 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2559 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2561 SEC_FLAG_MAXIMUM_ALLOWED,
2563 if (!W_ERROR_IS_OK(result))
2566 /* Enumerate subkeys */
2568 if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
2571 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
2573 if (!W_ERROR_IS_OK(result))
2576 for (i=0; i < ctr->num_values; i++) {
2577 display_reg_value(*(ctr->values[i]));
2583 if (is_valid_policy_hnd(&hnd))
2584 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2589 /****************************************************************************
2590 ****************************************************************************/
2592 static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
2593 TALLOC_CTX *mem_ctx, int argc,
2597 const char *printername;
2598 const char *keyname = NULL;
2600 uint16 *keylist = NULL, *curkey;
2602 if (argc < 2 || argc > 3) {
2603 printf("Usage: %s printername [keyname]\n", argv[0]);
2612 /* Open printer handle */
2614 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2616 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2618 SEC_FLAG_MAXIMUM_ALLOWED,
2620 if (!W_ERROR_IS_OK(result))
2623 /* Enumerate subkeys */
2625 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
2627 if (!W_ERROR_IS_OK(result))
2631 while (*curkey != 0) {
2632 char *subkey = NULL;
2633 rpcstr_pull_talloc(mem_ctx, &subkey, curkey, -1,
2638 printf("%s\n", subkey);
2639 curkey += strlen(subkey) + 1;
2646 if (is_valid_policy_hnd(&hnd))
2647 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2652 /****************************************************************************
2653 ****************************************************************************/
2655 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2656 TALLOC_CTX *mem_ctx, int argc,
2659 const char *printername;
2660 const char *clientname;
2664 struct spoolss_NotifyOption option;
2667 printf("Usage: %s printername\n", argv[0]);
2674 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2676 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2678 SEC_FLAG_MAXIMUM_ALLOWED,
2680 if (!W_ERROR_IS_OK(result)) {
2681 printf("Error opening %s\n", argv[1]);
2685 /* Create spool options */
2690 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
2691 if (option.types == NULL) {
2692 result = WERR_NOMEM;
2696 option.types[0].type = PRINTER_NOTIFY_TYPE;
2697 option.types[0].count = 1;
2698 option.types[0].fields = talloc_array(mem_ctx, enum spoolss_Field, 1);
2699 if (option.types[0].fields == NULL) {
2700 result = WERR_NOMEM;
2703 option.types[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2705 option.types[1].type = JOB_NOTIFY_TYPE;
2706 option.types[1].count = 1;
2707 option.types[1].fields = talloc_array(mem_ctx, enum spoolss_Field, 1);
2708 if (option.types[1].fields == NULL) {
2709 result = WERR_NOMEM;
2712 option.types[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2714 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
2716 result = WERR_NOMEM;
2722 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
2730 if (!W_ERROR_IS_OK(result)) {
2731 printf("Error rffpcnex %s\n", argv[1]);
2736 if (is_valid_policy_hnd(&hnd))
2737 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2742 /****************************************************************************
2743 ****************************************************************************/
2745 static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2746 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2748 union spoolss_PrinterInfo info1, info2;
2750 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
2752 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
2753 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
2758 if ( !W_ERROR_IS_OK(werror) ) {
2759 printf("failed (%s)\n", win_errstr(werror));
2760 talloc_destroy(mem_ctx);
2765 printf("Retrieving printer properties for %s...", cli2->desthost);
2766 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
2771 if ( !W_ERROR_IS_OK(werror) ) {
2772 printf("failed (%s)\n", win_errstr(werror));
2773 talloc_destroy(mem_ctx);
2778 talloc_destroy(mem_ctx);
2783 /****************************************************************************
2784 ****************************************************************************/
2786 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2787 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2789 union spoolss_PrinterInfo info1, info2;
2791 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
2792 SEC_DESC *sd1, *sd2;
2796 printf("Retrieving printer security for %s...", cli1->desthost);
2797 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
2802 if ( !W_ERROR_IS_OK(werror) ) {
2803 printf("failed (%s)\n", win_errstr(werror));
2809 printf("Retrieving printer security for %s...", cli2->desthost);
2810 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
2815 if ( !W_ERROR_IS_OK(werror) ) {
2816 printf("failed (%s)\n", win_errstr(werror));
2825 sd1 = info1.info3.secdesc;
2826 sd2 = info2.info3.secdesc;
2828 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
2829 printf("NULL secdesc!\n");
2834 if (!sec_desc_equal( sd1, sd2 ) ) {
2835 printf("Security Descriptors *not* equal!\n");
2840 printf("Security descriptors match\n");
2843 talloc_destroy(mem_ctx);
2848 /****************************************************************************
2849 ****************************************************************************/
2851 extern struct user_auth_info *rpcclient_auth_info;
2853 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
2854 TALLOC_CTX *mem_ctx, int argc,
2857 const char *printername;
2858 char *printername_path = NULL;
2859 struct cli_state *cli_server2 = NULL;
2860 struct rpc_pipe_client *cli2 = NULL;
2861 POLICY_HND hPrinter1, hPrinter2;
2866 printf("Usage: %s <printer> <server>\n", argv[0]);
2870 printername = argv[1];
2872 /* first get the connection to the remote server */
2874 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
2877 get_cmdline_auth_info_username(rpcclient_auth_info),
2879 get_cmdline_auth_info_password(rpcclient_auth_info),
2880 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
2881 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
2883 if ( !NT_STATUS_IS_OK(nt_status) )
2884 return WERR_GENERAL_FAILURE;
2886 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &syntax_spoolss,
2888 if (!NT_STATUS_IS_OK(nt_status)) {
2889 printf("failed to open spoolss pipe on server %s (%s)\n",
2890 argv[2], nt_errstr(nt_status));
2891 return WERR_GENERAL_FAILURE;
2894 /* now open up both printers */
2896 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
2898 printf("Opening %s...", printername_path);
2900 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2904 if ( !W_ERROR_IS_OK(werror) ) {
2905 printf("failed (%s)\n", win_errstr(werror));
2910 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
2912 printf("Opening %s...", printername_path);
2913 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
2917 if ( !W_ERROR_IS_OK(werror) ) {
2918 printf("failed (%s)\n", win_errstr(werror));
2923 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
2924 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
2926 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
2933 printf("Closing printers...");
2934 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
2935 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
2938 /* close the second remote connection */
2940 cli_shutdown( cli_server2 );
2944 /* List of commands exported by this module */
2945 struct cmd_set spoolss_commands[] = {
2949 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &syntax_spoolss, NULL, "Add a print driver", "" },
2950 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &syntax_spoolss, NULL, "Add a printer", "" },
2951 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &syntax_spoolss, NULL, "Delete a printer driver", "" },
2952 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &syntax_spoolss, NULL, "Delete a printer driver with files", "" },
2953 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &syntax_spoolss, NULL, "Enumerate printer data", "" },
2954 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" },
2955 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" },
2956 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" },
2957 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" },
2958 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" },
2959 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" },
2960 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &syntax_spoolss, NULL, "Get print driver data", "" },
2961 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &syntax_spoolss, NULL, "Get printer driver data with keyname", ""},
2962 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &syntax_spoolss, NULL, "Get print driver information", "" },
2963 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &syntax_spoolss, NULL, "Get print driver upload directory", "" },
2964 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &syntax_spoolss, NULL, "Get printer info", "" },
2965 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &syntax_spoolss, NULL, "Open printer handle", "" },
2966 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &syntax_spoolss, NULL, "Set printer driver", "" },
2967 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &syntax_spoolss, NULL, "Get print processor directory", "" },
2968 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &syntax_spoolss, NULL, "Add form", "" },
2969 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &syntax_spoolss, NULL, "Set form", "" },
2970 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &syntax_spoolss, NULL, "Get form", "" },
2971 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &syntax_spoolss, NULL, "Delete form", "" },
2972 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &syntax_spoolss, NULL, "Enumerate forms", "" },
2973 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &syntax_spoolss, NULL, "Set printer comment", "" },
2974 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &syntax_spoolss, NULL, "Set printername", "" },
2975 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &syntax_spoolss, NULL, "Set REG_SZ printer data", "" },
2976 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &syntax_spoolss, NULL, "Rffpcnex test", "" },
2977 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &syntax_spoolss, NULL, "Printer comparison test", "" },