diff options
author | Tim Potter <tpot@samba.org> | 2001-12-10 05:03:17 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 2001-12-10 05:03:17 +0000 |
commit | 4f53486d78102d8080293eeafd7b4ed701d81a2e (patch) | |
tree | 2aaca817b8f8dbbb1fb09abff6ad482398b7dd1d /source3 | |
parent | ce654f5e557544451fb198b32af89152a2aeed60 (diff) | |
download | samba-4f53486d78102d8080293eeafd7b4ed701d81a2e.tar.gz samba-4f53486d78102d8080293eeafd7b4ed701d81a2e.tar.bz2 samba-4f53486d78102d8080293eeafd7b4ed701d81a2e.zip |
Added client and server code for the GetPrintProcessorDirectory SPOOLSS
rpc. This was supposed to fix a printer driver download bug but it didn't
but it seemed a shame to trash all this code so I'm commiting it #ifdef'ed
out in case someone needs it one day.
(This used to be commit bef43656471741c6c10b12e7516c15de9ae76394)
Diffstat (limited to 'source3')
-rwxr-xr-x | source3/include/rpc_spoolss.h | 27 | ||||
-rw-r--r-- | source3/libsmb/cli_spoolss.c | 59 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 141 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 40 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 86 | ||||
-rw-r--r-- | source3/rpcclient/cmd_spoolss.c | 32 |
6 files changed, 380 insertions, 5 deletions
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 0a8455ebbb..bd9de92dcb 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -4,7 +4,8 @@ SMB parameters and setup Copyright (C) Andrew Tridgell 1992-2000, Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean Francois Micouleau 1998-2000. + Copyright (C) Jean Francois Micouleau 1998-2000, + Copyright (C) Tim Potter 2001. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,7 +31,6 @@ /* spoolss pipe: this are the calls which are not implemented ... #define SPOOLSS_OPENPRINTER 0x01 #define SPOOLSS_GETPRINTERDRIVER 0x0b -#define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10 #define SPOOLSS_READPRINTER 0x16 #define SPOOLSS_WAITFORPRINTERCHANGE 0x1c #define SPOOLSS_ADDPORT 0x25 @@ -77,6 +77,7 @@ #define SPOOLSS_DELETEPRINTERDRIVER 0x0d #define SPOOLSS_ADDPRINTPROCESSOR 0x0e #define SPOOLSS_ENUMPRINTPROCESSORS 0x0f +#define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10 #define SPOOLSS_STARTDOCPRINTER 0x11 #define SPOOLSS_STARTPAGEPRINTER 0x12 #define SPOOLSS_WRITEPRINTER 0x13 @@ -1955,7 +1956,29 @@ typedef struct spool_r_enumprinterdataex } SPOOL_R_ENUMPRINTERDATAEX; +typedef struct printprocessor_directory_1 +{ + UNISTR name; +} +PRINTPROCESSOR_DIRECTORY_1; + +typedef struct spool_q_getprintprocessordirectory +{ + UNISTR2 name; + UNISTR2 environment; + uint32 level; + NEW_BUFFER *buffer; + uint32 offered; +} +SPOOL_Q_GETPRINTPROCESSORDIRECTORY; +typedef struct spool_r_getprintprocessordirectory +{ + NEW_BUFFER *buffer; + uint32 needed; + WERROR status; +} +SPOOL_R_GETPRINTPROCESSORDIRECTORY; #define PRINTER_DRIVER_VERSION 2 #define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86" diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 2663e311e0..d455bb7196 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1070,4 +1070,63 @@ done: return result; } +NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *name, + char *environment, + fstring procdir) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; + SPOOL_R_GETPRINTPROCESSORDIRECTORY r; + NTSTATUS result; + int level = 1; + NEW_BUFFER buffer; + uint32 needed = 100; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + + /* Initialise input parameters */ + + do { + init_buffer(&buffer, needed, 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); + + /* 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; + } + + /* Unmarshall response */ + + if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + result = werror_to_ntstatus(r.status); + + } while (NT_STATUS_V(result) == + NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index a376b19c98..b4d6343946 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -4,8 +4,9 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - * Copyright (C) Jean François Micouleau 1998-2000. - * Copyright (C) Gerald Carter 2000 + * Copyright (C) Jean François Micouleau 1998-2000, + * Copyright (C) Gerald Carter 2000, + * Copyright (C) Tim Potter 2001. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -3171,6 +3172,21 @@ uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info) return the size required by a struct in the stream ********************************************************************/ +uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info) +{ + int size=0; + + size=str_len_uni(&info->name); /* the string length */ + size=size+1; /* add the leading zero */ + size=size*2; /* convert in char */ + + return size; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ + uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) { int size=0; @@ -6433,3 +6449,124 @@ BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, } +/******************************************************************* + * write a structure. + ********************************************************************/ + +/* + uint32 GetPrintProcessorDirectory( + [in] unistr2 *name, + [in] unistr2 *environment, + [in] uint32 level, + [in,out] NEW_BUFFER buffer, + [in] uint32 offered, + [out] uint32 needed, + [out] uint32 returned + ); + +*/ + +BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered) +{ + DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n")); + + init_unistr2(&q_u->name, name, strlen(name)+1); + init_unistr2(&q_u->environment, environment, strlen(environment)+1); + + q_u->level = level; + + q_u->buffer = buffer; + q_u->offered = offered; + + return True; +} + +BOOL spoolss_io_q_getprintprocessordirectory(char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth) +{ + uint32 ptr; + + prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory"); + depth++; + + if(!prs_align(ps)) + return False; + + if (!prs_uint32("ptr", ps, depth, &ptr)) + return False; + + if (ptr) { + if(!smb_io_unistr2("name", &q_u->name, True, ps, depth)) + return False; + } + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr", ps, depth, &ptr)) + return False; + + if (ptr) { + if(!smb_io_unistr2("environment", &q_u->environment, True, + ps, depth)) + return False; + } + + if (!prs_align(ps)) + return False; + + if(!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + ********************************************************************/ + +BOOL spoolss_io_r_getprintprocessordirectory(char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + +BOOL smb_io_printprocessordirectory_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth) +{ + prs_struct *ps=&buffer->prs; + + prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!smb_io_unistr(desc, &info->name, ps, depth)) + return False; + + return True; +} diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 3a056dcb65..e71bcd36a9 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -1316,6 +1316,40 @@ static BOOL api_spoolss_enumprinterdataex(pipes_struct *p) return True; } +/**************************************************************************** +****************************************************************************/ + +/* Disabled because it doesn't fix the bug I am looking at but it would be + a shame to throw away the code. -tpot */ + +#if 0 + +static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p) +{ + SPOOL_Q_GETPRINTPROCESSORDIRECTORY q_u; + SPOOL_R_GETPRINTPROCESSORDIRECTORY r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!spoolss_io_q_getprintprocessordirectory("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprintprocessordirectory: unable to unmarshall SPOOL_Q_GETPRINTPROCESSORDIRECTORY.\n")); + return False; + } + + r_u.status = _spoolss_getprintprocessordirectory(p, &q_u, &r_u); + + if(!spoolss_io_r_getprintprocessordirectory("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_getprintprocessordirectory: unable to marshall SPOOL_R_GETPRINTPROCESSORDIRECTORY.\n")); + return False; + } + + return True; +} + +#endif /******************************************************************* \pipe\spoolss commands @@ -1367,7 +1401,11 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_SETPRINTERDATAEX", SPOOLSS_SETPRINTERDATAEX, api_spoolss_setprinterdataex }, {"SPOOLSS_ENUMPRINTERKEY", SPOOLSS_ENUMPRINTERKEY, api_spoolss_enumprinterkey }, {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex }, - +#if 0 + /* Disabled because it doesn't fix the bug I am looking at but it would be + a shame to throw away the code. -tpot */ + {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory}, +#endif { NULL, 0, NULL } }; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 0e98498fe3..dae3aa09c9 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -7,6 +7,7 @@ * Copyright (C) Jean François Micouleau 1998-2000. * Copyright (C) Jeremy Allison 2001. * Copyright (C) Gerald Carter 2000-2001. + * Copyright (C) Tim Potter 2001. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -7073,4 +7074,89 @@ done: return result; } +/**************************************************************************** +****************************************************************************/ + +/* Disabled because it doesn't fix the bug I am looking at but it would be + a shame to throw away the code. -tpot */ + +#if 0 + +static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name) +{ + init_unistr(&info->name, name); +} + +static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, + UNISTR2 *environment, + NEW_BUFFER *buffer, + uint32 offered, + uint32 *needed) +{ + pstring path; + pstring long_archi; + pstring short_archi; + PRINTPROCESSOR_DIRECTORY_1 *info=NULL; + + unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1); + + if (get_short_archi(short_archi, long_archi)==FALSE) + return WERR_INVALID_ENVIRONMENT; + + if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL) + return WERR_NOMEM; + + /* Not sure what to return here - are UNC names valid here?. + Windows returns the string: C:\WINNT\System32\spool\PRTPROCS\W32X86 + which is pretty bogus for a RPC. */ + + slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi); + + DEBUG(4,("print processor directory: [%s]\n", path)); + + fill_printprocessordirectory_1(info, path); + + *needed += spoolss_size_printprocessordirectory_info_1(info); + + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(info); + return WERR_INSUFFICIENT_BUFFER; + } + + smb_io_printprocessordirectory_1("", buffer, info, 0); + safe_free(info); + + if (*needed > offered) + return WERR_INSUFFICIENT_BUFFER; + else + return WERR_OK; +} + +WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u) +{ + uint32 level = q_u->level; + NEW_BUFFER *buffer = NULL; + uint32 offered = q_u->offered; + uint32 *needed = &r_u->needed; + + /* that's an [in out] buffer */ + spoolss_move_buffer(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + + DEBUG(5,("_spoolss_getprintprocessordirectory\n")); + + *needed=0; + + switch(level) { + case 1: + return getprintprocessordirectory_level_1 + (&q_u->name, &q_u->environment, buffer, offered, needed); + default: + return WERR_UNKNOWN_LEVEL; + } + + return WERR_ACCESS_DENIED; +} + +#endif diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index bc003284da..2f80295a53 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1149,6 +1149,37 @@ static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli, return NT_STATUS_OK; } +static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int argc, char **argv) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + char *servername = NULL, *environment = NULL; + fstring procdir; + + /* parse the command arguements */ + if (argc < 2 || argc > 3) { + printf ("Usage: %s <server> [environment]\n", argv[0]); + return NT_STATUS_OK; + } + + asprintf(&servername, "\\\\%s", cli->desthost); + strupper(servername); + + asprintf(&environment, "%s", (argc == 3) ? argv[2] : + PRINTER_DRIVER_ARCHITECTURE); + + result = cli_spoolss_getprintprocessordirectory( + cli, mem_ctx, servername, environment, procdir); + + if (NT_STATUS_IS_OK(result)) + printf("%s", procdir); + + SAFE_FREE(servername); + SAFE_FREE(environment); + + return result; +} /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { @@ -1169,6 +1200,7 @@ struct cmd_set spoolss_commands[] = { { "getprinter", cmd_spoolss_getprinter, PIPE_SPOOLSS, "Get printer info", "" }, { "openprinter", cmd_spoolss_open_printer_ex, PIPE_SPOOLSS, "Open printer handle", "" }, { "setdriver", cmd_spoolss_setdriver, PIPE_SPOOLSS, "Set printer driver", "" }, + { "getprintprocdir", cmd_spoolss_getprintprocdir, PIPE_SPOOLSS, "Get print processor directory", "" }, { NULL } }; |