From e026103a975c3ab16f99118a53f585e7d34ad1da Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 20 Feb 2002 18:41:07 +0000 Subject: Converted remaining spoolss rpcclient functions to werror/needed/offered. I couldn't test some of these because I didn't know the right magic arguments to pass to rpcclient (familiar anyone? (-:) so there may be some bugs lurking. (This used to be commit 029e2b307d91171168040e71d2e5d5e0d01b7633) --- source3/libsmb/cli_spoolss.c | 278 ++++++++++++++++++---------------------- source3/rpcclient/cmd_spoolss.c | 112 ++++++++-------- 2 files changed, 188 insertions(+), 202 deletions(-) diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 661543ebfa..c11debba33 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -582,6 +582,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, } /* Get printer info */ + WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, POLICY_HND *pol, uint32 level, @@ -647,53 +648,57 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/********************************************************************** - * Set printer info +/** Set printer info + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param pol Policy handle on printer to set info. + * @param level Information level to set. + * @param ctr Pointer to structure holding printer information. + * @param command Specifies the action performed. See + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp + * for details. + * */ -NTSTATUS cli_spoolss_setprinter( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint32 level, - PRINTER_INFO_CTR *ctr, - uint32 command -) + +WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 level, + PRINTER_INFO_CTR *ctr, uint32 command) { prs_struct qbuf, rbuf; SPOOL_Q_SETPRINTER q; SPOOL_R_SETPRINTER r; - NTSTATUS result = NT_STATUS_ACCESS_DENIED; + WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); /* Marshall data and send request */ + if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) - { - result = NT_STATUS_ACCESS_DENIED; + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) - { + + if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) goto done; - } - result = werror_to_ntstatus(r.status); - + result = r.status; + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return result; } @@ -870,20 +875,17 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, /********************************************************************** * Get installed printer drivers for a given printer */ -NTSTATUS cli_spoolss_getprinterdriverdir ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - char* env, - DRIVER_DIRECTORY_CTR *ctr -) +WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + uint32 level, char *env, + DRIVER_DIRECTORY_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDRIVERDIR q; SPOOL_R_GETPRINTERDRIVERDIR r; NEW_BUFFER buffer; - uint32 needed = 100; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -892,67 +894,63 @@ NTSTATUS cli_spoolss_getprinterdriverdir ( slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - do - { - /* Initialise input parameters */ - init_buffer(&buffer, needed, mem_ctx); + /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + init_buffer(&buffer, offered, mem_ctx); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Write the request */ - /* write the request */ - make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, needed); + make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, + offered); - /* Marshall data and send request */ - if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &qbuf, &rbuf)) - { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + /* Marshall data and send request */ - /* Unmarshall response */ - if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) - { - needed = r.needed; - } + if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, + &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) { + if (needed) + *needed = r.needed; + } - /* Return output parameters */ - result = werror_to_ntstatus(r.status); - if (NT_STATUS_IS_OK(result)) - { - switch (level) - { - case 1: - decode_printerdriverdir_1(mem_ctx, r.buffer, 1, &ctr->info1); - break; - } - } + /* Return output parameters */ + + result = r.status; + if (W_ERROR_IS_OK(result)) { + switch (level) { + case 1: + decode_printerdriverdir_1(mem_ctx, r.buffer, 1, + &ctr->info1); + break; + } + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); - - return result; + return result; } /********************************************************************** * Install a printer driver */ -NTSTATUS cli_spoolss_addprinterdriver ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - PRINTER_DRIVER_CTR *ctr -) +WERROR cli_spoolss_addprinterdriver (struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, + PRINTER_DRIVER_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTERDRIVER q; SPOOL_R_ADDPRINTERDRIVER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -962,31 +960,28 @@ NTSTATUS cli_spoolss_addprinterdriver ( strupper (server); /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + /* Write the request */ - /* write the request */ make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) - { + !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) goto done; - } - /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) - { goto done; - } /* Return output parameters */ - result = werror_to_ntstatus(r.status); + + result = r.status; done: prs_mem_free(&qbuf); @@ -998,17 +993,13 @@ done: /********************************************************************** * Install a printer */ -NTSTATUS cli_spoolss_addprinterex ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - PRINTER_INFO_CTR *ctr -) +WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 level, PRINTER_INFO_CTR*ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTEREX q; SPOOL_R_ADDPRINTEREX r; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server, client, user; @@ -1021,36 +1012,33 @@ NTSTATUS cli_spoolss_addprinterex ( slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); fstrcpy (user, cli->user_name); - /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + /* Write the request */ - /* write the request */ - make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, level, ctr); + make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, + level, ctr); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) - { goto done; - } - /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) - { goto done; - } /* Return output parameters */ - result = werror_to_ntstatus(r.status); -done: + result = r.status; + + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); @@ -1061,53 +1049,47 @@ done: * Delete a Printer Driver from the server (does not remove * the driver files */ -NTSTATUS cli_spoolss_deleteprinterdriver ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *arch, - char *driver -) +WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, + TALLOC_CTX *mem_ctx, char *arch, + char *driver) { prs_struct qbuf, rbuf; SPOOL_Q_DELETEPRINTERDRIVER q; SPOOL_R_DELETEPRINTERDRIVER r; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); - /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - /* write the request */ - make_spoolss_q_deleteprinterdriver (mem_ctx, &q, server, arch, driver); + /* Write the request */ + + make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) - { + !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) goto done; - } - /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) - { goto done; - } /* Return output parameters */ - result = werror_to_ntstatus(r.status); -done: + result = r.status; + + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); @@ -1116,59 +1098,55 @@ done: /* Get print processor directory */ -NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *name, - char *environment, - fstring procdir) +WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + char *name, char *environment, + fstring procdir) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; SPOOL_R_GETPRINTPROCESSORDIRECTORY r; - NTSTATUS result; int level = 1; + WERROR result = W_ERROR(ERRgeneral); NEW_BUFFER buffer; - uint32 needed = 100; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ - do { - init_buffer(&buffer, needed, mem_ctx); + init_buffer(&buffer, offered, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprintprocessordirectory(&q, name, - environment, level, - &buffer, needed); + make_spoolss_q_getprintprocessordirectory( + &q, name, environment, level, &buffer, offered); - /* Marshall data and send request */ + /* Marshall data and send request */ - if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, + &qbuf, &rbuf)) + goto done; - /* Unmarshall response */ + /* Unmarshall response */ - if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) + goto done; - /* Return output parameters */ + /* Return output parameters */ - result = werror_to_ntstatus(r.status); + result = r.status; + + if (needed) + *needed = r.needed; - } while (NT_STATUS_V(result) == - NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + if (W_ERROR_IS_OK(result)) + fstrcpy(procdir, "Not implemented!"); done: prs_mem_free(&qbuf); diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index a556783368..75c0cc0245 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -717,7 +717,7 @@ static NTSTATUS cmd_spoolss_getdriver(struct cli_state *cli, if (opened_hnd) cli_spoolss_close_printer (cli, mem_ctx, &pol); - return result; + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /*********************************************************************** @@ -815,32 +815,36 @@ static NTSTATUS cmd_spoolss_getdriverdir(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { - NTSTATUS result; + WERROR result; fstring env; DRIVER_DIRECTORY_CTR ctr; + uint32 needed; - if (argc > 2) - { + if (argc > 2) { printf("Usage: %s [environment]\n", argv[0]); return NT_STATUS_OK; } - /* get the arguments need to open the printer handle */ + /* Get the arguments need to open the printer handle */ + if (argc == 2) fstrcpy (env, argv[1]); else fstrcpy (env, "Windows NT x86"); /* Get the directory. Only use Info level 1 */ - result = cli_spoolss_getprinterdriverdir (cli, mem_ctx, 1, env, &ctr); - if (!NT_STATUS_IS_OK(result)) { - return result; - } - - display_printdriverdir_1 (ctr.info1); + result = cli_spoolss_getprinterdriverdir( + cli, mem_ctx, 0, &needed, 1, env, &ctr); + + if (W_ERROR_V(result) == ERRinsufficientbuffer) + result = cli_spoolss_getprinterdriverdir( + cli, mem_ctx, needed, NULL, 1, env, &ctr); - return result; + if (W_ERROR_IS_OK(result)) + display_printdriverdir_1(ctr.info1); + + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /******************************************************************************* @@ -955,7 +959,7 @@ static NTSTATUS cmd_spoolss_addprinterdriver(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { - NTSTATUS result; + WERROR result; uint32 level = 3; PRINTER_DRIVER_CTR ctr; DRIVER_INFO_3 info3; @@ -992,14 +996,15 @@ static NTSTATUS cmd_spoolss_addprinterdriver(struct cli_state *cli, ctr.info3 = &info3; result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr); - if (!NT_STATUS_IS_OK(result)) { - return result; - } - rpcstr_pull(driver_name, info3.name.buffer, sizeof(driver_name), 0, STR_TERMINATE); - printf ("Printer Driver %s successfully installed.\n", driver_name); + if (W_ERROR_IS_OK(result)) { + rpcstr_pull(driver_name, info3.name.buffer, + sizeof(driver_name), 0, STR_TERMINATE); + printf ("Printer Driver %s successfully installed.\n", + driver_name); + } - return result; + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } @@ -1007,7 +1012,7 @@ static NTSTATUS cmd_spoolss_addprinterex(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { - NTSTATUS result; + WERROR result; uint32 level = 2; PRINTER_INFO_CTR ctr; PRINTER_INFO_2 info2; @@ -1053,13 +1058,11 @@ static NTSTATUS cmd_spoolss_addprinterex(struct cli_state *cli, ctr.printers_2 = &info2; result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr); - if (!NT_STATUS_IS_OK(result)) { - return result; - } - printf ("Printer %s successfully installed.\n", argv[1]); + if (W_ERROR_IS_OK(result)) + printf ("Printer %s successfully installed.\n", argv[1]); - return result; + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli, @@ -1068,7 +1071,6 @@ static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli, { POLICY_HND pol; WERROR result; - NTSTATUS nt_status; uint32 level = 2; BOOL opened_hnd = False; PRINTER_INFO_CTR ctr; @@ -1096,11 +1098,9 @@ static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli, MAXIMUM_ALLOWED_ACCESS, servername, user, &pol); - nt_status = W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; - - if (!NT_STATUS_IS_OK(nt_status)) + if (!W_ERROR_IS_OK(result)) goto done; - + opened_hnd = True; /* Get printer info */ @@ -1124,9 +1124,9 @@ static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli, init_unistr(&ctr.printers_2->drivername, argv[2]); - nt_status = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0); + result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0); - if (!NT_STATUS_IS_OK(nt_status)) { + if (!W_ERROR_IS_OK(result)) { printf("SetPrinter call failed!\n"); goto done;; } @@ -1139,7 +1139,7 @@ done: if (opened_hnd) cli_spoolss_close_printer(cli, mem_ctx, &pol); - return nt_status; + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } @@ -1147,7 +1147,7 @@ static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result; fstring servername; int i; @@ -1165,30 +1165,33 @@ static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli, for (i=0; archi_table[i].long_archi; i++) { /* make the call to remove the driver */ - result = cli_spoolss_deleteprinterdriver(cli, mem_ctx, - archi_table[i].long_archi, argv[1]); - if (!NT_STATUS_IS_OK(result)) { - printf ("Failed to remove driver %s for arch [%s] - error %s!\n", - argv[1], archi_table[i].long_archi, get_nt_error_msg(result)); - } - else - printf ("Driver %s removed for arch [%s].\n", argv[1], archi_table[i].long_archi); + result = cli_spoolss_deleteprinterdriver( + cli, mem_ctx, archi_table[i].long_archi, argv[1]); + + if (!W_ERROR_IS_OK(result)) { + printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n", + argv[1], archi_table[i].long_archi, + W_ERROR_V(result)); + } else + printf ("Driver %s removed for arch [%s].\n", argv[1], + archi_table[i].long_archi); } - return NT_STATUS_OK; + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result; char *servername = NULL, *environment = NULL; fstring procdir; + uint32 needed; /* parse the command arguements */ - if (argc < 2 || argc > 3) { - printf ("Usage: %s [environment]\n", argv[0]); + if (argc > 2) { + printf ("Usage: %s [environment]\n", argv[0]); return NT_STATUS_OK; } @@ -1196,22 +1199,27 @@ static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli, return NT_STATUS_NO_MEMORY; strupper(servername); - if (asprintf(&environment, "%s", (argc == 3) ? argv[2] : - PRINTER_DRIVER_ARCHITECTURE) < 0) { + if (asprintf(&environment, "%s", (argc == 2) ? argv[1] : + PRINTER_DRIVER_ARCHITECTURE) < 0) { SAFE_FREE(servername); return NT_STATUS_NO_MEMORY; } result = cli_spoolss_getprintprocessordirectory( - cli, mem_ctx, servername, environment, procdir); + cli, mem_ctx, 0, &needed, servername, environment, procdir); + + if (W_ERROR_V(result) == ERRinsufficientbuffer) + result = cli_spoolss_getprintprocessordirectory( + cli, mem_ctx, needed, NULL, servername, environment, + procdir); - if (NT_STATUS_IS_OK(result)) - printf("%s", procdir); + if (W_ERROR_IS_OK(result)) + printf("%s\n", procdir); SAFE_FREE(servername); SAFE_FREE(environment); - return result; + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /* Add a form */ -- cgit