diff options
-rwxr-xr-x | source3/include/rpc_spoolss.h | 41 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 142 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 63 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 38 |
4 files changed, 283 insertions, 1 deletions
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 82d7d70d4f..2962546122 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -57,7 +57,6 @@ #define SPOOLSS_SPOOLERINIT 0x3f #define SPOOLSS_RESETPRINTEREX 0x40 #define SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION 0x42 -#define SPOOLSS_GETPRINTERDATAEX 0x4e */ /* those are implemented */ @@ -109,6 +108,8 @@ #define SPOOLSS_ADDPRINTEREX 0x46 #define SPOOLSS_ENUMPRINTERDATA 0x48 #define SPOOLSS_DELETEPRINTERDATA 0x49 +#define SPOOLSS_GETPRINTERDATAEX 0x4e +#define SPOOLSS_SETPRINTERDATAEX 0xff /* unknown */ #define PRINTER_CONTROL_UNPAUSE 0x00000000 #define PRINTER_CONTROL_PAUSE 0x00000001 @@ -1857,6 +1858,44 @@ typedef struct spool_r_rrpcn } SPOOL_R_REPLY_RRPCN; +typedef struct spool_q_getprinterdataex +{ + POLICY_HND handle; + UNISTR2 keyname; + UNISTR2 valuename; + uint32 size; +} +SPOOL_Q_GETPRINTERDATAEX; + +typedef struct spool_r_getprinterdataex +{ + uint32 type; + uint32 size; + uint8 *data; + uint32 needed; + WERROR status; +} +SPOOL_R_GETPRINTERDATAEX; + +typedef struct spool_q_setprinterdataex +{ + POLICY_HND handle; + UNISTR2 key; + UNISTR2 value; + uint32 type; + uint32 max_len; + uint8 *data; + uint32 real_len; + uint32 numeric_data; +} +SPOOL_Q_SETPRINTERDATAEX; + +typedef struct spool_r_setprinterdataex +{ + WERROR status; +} +SPOOL_R_SETPRINTERDATAEX; + #define PRINTER_DRIVER_VERSION 2 #define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86" diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 76e06a343a..b86c595c64 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -6097,3 +6097,145 @@ BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct * return True; } + +/******************************************************************* + * read a structure. + * called from spoolss_q_getprinterdataex (srv_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_q_getprinterdataex(char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex"); + depth++; + + if (!prs_align(ps)) + return False; + if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) + return False; + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth)) + return False; + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth)) + return False; + if (!prs_align(ps)) + return False; + if (!prs_uint32("size", ps, depth, &q_u->size)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_getprinterdataex (srv_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_r_getprinterdataex(char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("type", ps, depth, &r_u->type)) + return False; + if (!prs_uint32("size", ps, depth, &r_u->size)) + return False; + + if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size)) + 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; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_setprinterdataex (srv_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_q_setprinterdataex(char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex"); + depth++; + + if(!prs_align(ps)) + return False; + if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + if(!smb_io_unistr2("", &q_u->key, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!smb_io_unistr2("", &q_u->value, True, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("type", ps, depth, &q_u->type)) + return False; + + if(!prs_uint32("max_len", ps, depth, &q_u->max_len)) + return False; + + switch (q_u->type) + { + case 0x1: + case 0x3: + case 0x4: + case 0x7: + if (q_u->max_len) { + if (UNMARSHALLING(ps)) + q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8)); + if(q_u->data == NULL) + return False; + if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len)) + return False; + } + if(!prs_align(ps)) + return False; + break; + } + + if(!prs_uint32("real_len", ps, depth, &q_u->real_len)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_q_setprinterdataex (srv_spoolss.c) + ********************************************************************/ + +BOOL spoolss_io_r_setprinterdataex(char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex"); + depth++; + + if(!prs_align(ps)) + return False; + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index a5ae418cd4..27331e448b 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -1199,6 +1199,66 @@ static BOOL api_spoolss_getjob(pipes_struct *p) return True; } +/******************************************************************** + * api_spoolss_getprinterdataex + * + * called from the spoolss dispatcher + ********************************************************************/ + +static BOOL api_spoolss_getprinterdataex(pipes_struct *p) +{ + SPOOL_Q_GETPRINTERDATAEX q_u; + SPOOL_R_GETPRINTERDATAEX r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* read the stream and fill the struct */ + if (!spoolss_io_q_getprinterdataex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinterdataex: unable to unmarshall SPOOL_Q_GETPRINTERDATAEX.\n")); + return False; + } + + r_u.status = _spoolss_getprinterdataex( p, &q_u, &r_u); + + if (!spoolss_io_r_getprinterdataex("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_getprinterdataex: unable to marshall SPOOL_R_GETPRINTERDATAEX.\n")); + return False; + } + + return True; +} + +/**************************************************************************** +****************************************************************************/ + +static BOOL api_spoolss_setprinterdataex(pipes_struct *p) +{ + SPOOL_Q_SETPRINTERDATAEX q_u; + SPOOL_R_SETPRINTERDATAEX 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_setprinterdataex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setprinterdataex: unable to unmarshall SPOOL_Q_SETPRINTERDATAEX.\n")); + return False; + } + + r_u.status = _spoolss_setprinterdataex(p, &q_u, &r_u); + + if(!spoolss_io_r_setprinterdataex("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_setprinterdataex: unable to marshall SPOOL_R_SETPRINTERDATAEX.\n")); + return False; + } + + return True; +} + /******************************************************************* \pipe\spoolss commands ********************************************************************/ @@ -1245,6 +1305,9 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors }, {"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob }, {"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes }, + {"SPOOLSS_GETPRINTERDATAEX", SPOOLSS_GETPRINTERDATAEX, api_spoolss_getprinterdataex }, + {"SPOOLSS_sETPRINTERDATAEX", SPOOLSS_SETPRINTERDATAEX, api_spoolss_setprinterdataex }, + { NULL, 0, NULL } }; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 0be836c944..e5ca373479 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -6755,3 +6755,41 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ return WERR_UNKNOWN_LEVEL; } } + +/******************************************************************** + * spoolss_getprinterdataex + ********************************************************************/ + +WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u) +{ + fstring key; + + /* From MSDN documentation of GetPrinterDataEx: pass request to + GetPrinterData if key is "PrinterDriverData" */ + + unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); + + if (strcmp(key, "PrinterDriverData") == 0) + DEBUG(10, ("pass me to getprinterdata\n")); + + return WERR_INVALID_PARAM; +} + +/******************************************************************** + * spoolss_setprinterdata + ********************************************************************/ + +WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u) +{ + fstring key; + + /* From MSDN documentation of SetPrinterDataEx: pass request to + SetPrinterData if key is "PrinterDriverData" */ + + unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1); + + if (strcmp(key, "PrinterDriverData") == 0) + DEBUG(10, ("pass me to setprinterdata\n")); + + return WERR_INVALID_PARAM; +} |