diff options
-rw-r--r-- | source3/include/proto.h | 8 | ||||
-rwxr-xr-x | source3/include/rpc_spoolss.h | 48 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 89 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 109 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 117 |
5 files changed, 363 insertions, 8 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 41a68296d2..5ddcc0e650 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1581,6 +1581,9 @@ struct passgrp_ops *unix_initialise_password_grp(void); /*The following definitions come from printing/nt_printing.c */ int get_ntforms(nt_forms_struct **list); +int write_ntforms(nt_forms_struct **list, int number); +void add_a_form(nt_forms_struct **list, FORM form, int count); +void update_a_form(nt_forms_struct **list, FORM form, int count); int get_ntdrivers(connection_struct *conn, fstring **list, char *architecture); void get_short_archi(char *short_archi, char *long_archi); void dump_a_param(NT_PRINTER_PARAM *param); @@ -2748,6 +2751,7 @@ void spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, void spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth); +void spoolss_io_free_buffer(BUFFER *buffer); void spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); @@ -2814,6 +2818,10 @@ void spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_ void spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth); void spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth); void convert_specific_param(NT_PRINTER_PARAM **param, UNISTR2 value , uint32 type, uint8 *data, uint32 len); +void spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth); +void spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth); +void spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth); +void spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_srv.c */ diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index f8e7efe81b..8476ad7691 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -38,10 +38,8 @@ #define SPOOLSS_ABORTPRINTER 0x15 #define SPOOLSS_READPRINTER 0x16 #define SPOOLSS_WAITFORPRINTERCHANGE 0x1c -#define SPOOLSS_ADDFORM 0x1e #define SPOOLSS_DELETEFORM 0x1f #define SPOOLSS_GETFORM 0x20 -#define SPOOLSS_SETFORM 0x21 #define SPOOLSS_ENUMMONITORS 0x24 #define SPOOLSS_ADDPORT 0x25 #define SPOOLSS_CONFIGUREPORT 0x26 @@ -93,6 +91,8 @@ #define SPOOLSS_GETPRINTERDATA 0x1a #define SPOOLSS_SETPRINTERDATA 0x1b #define SPOOLSS_CLOSEPRINTER 0x1d +#define SPOOLSS_ADDFORM 0x1e +#define SPOOLSS_SETFORM 0x21 #define SPOOLSS_ENUMFORMS 0x22 #define SPOOLSS_ENUMPORTS 0x23 #define SPOOLSS_ENUMPRINTPROCESSORDATATYPES 0x33 @@ -1398,12 +1398,52 @@ typedef struct spool_q_setprinterdata uint8 *data; uint32 real_len; uint32 numeric_data; -}SPOOL_Q_SETPRINTERDATA; +} SPOOL_Q_SETPRINTERDATA; typedef struct spool_r_setprinterdata { uint32 status; -}SPOOL_R_SETPRINTERDATA; +} SPOOL_R_SETPRINTERDATA; + +typedef struct _form +{ + uint32 flags; + uint32 name_ptr; + uint32 size_x; + uint32 size_y; + uint32 left; + uint32 top; + uint32 right; + uint32 bottom; + UNISTR2 name; +} FORM; + +typedef struct spool_q_addform +{ + PRINTER_HND handle; + uint32 level; + uint32 level2; + FORM form; +} SPOOL_Q_ADDFORM; + +typedef struct spool_r_addform +{ + uint32 status; +} SPOOL_R_ADDFORM; + +typedef struct spool_q_setform +{ + PRINTER_HND handle; + UNISTR2 name; + uint32 level; + uint32 level2; + FORM form; +} SPOOL_Q_SETFORM; + +typedef struct spool_r_setform +{ + uint32 status; +} SPOOL_R_SETFORM; #define PRINTER_DRIVER_VERSION 2 #define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86" diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 76b9ee909d..0757d08b8c 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -87,11 +87,98 @@ int get_ntforms(nt_forms_struct **list) return(total); } +/**************************************************************************** +write a form struct list +****************************************************************************/ +int write_ntforms(nt_forms_struct **list, int number) +{ + FILE *f; + pstring line; + char *file = lp_nt_forms(); + int total=0; + int i; + + *line=0; + + DEBUG(6,("write_ntforms\n")); + + if((f = sys_fopen(file, "w")) == NULL) + { + DEBUG(1, ("cannot create forms file [%s]\n", file)); + return(0); + } + + for (i=0; i<number;i++) + { + + fprintf(f,"%s:%d:%d:%d:%d:%d:%d:%d\n", (*list)[i].name, + (*list)[i].flag, (*list)[i].width, (*list)[i].length, + (*list)[i].left, (*list)[i].top, (*list)[i].right, (*list)[i].bottom); + + DEBUGADD(7,("adding entry [%s]\n", (*list)[i].name)); + } + + fclose(f); + DEBUGADD(6,("closing file\n")); + return(total); +} + +/**************************************************************************** +add a form struct at the end of the list +****************************************************************************/ +void add_a_form(nt_forms_struct **list, FORM form, int count) +{ + int n=count; + + *list=Realloc(*list, (n+1)*sizeof(nt_forms_struct)); + + (*list)[n].flag=form.flags; + (*list)[n].width=form.size_x; + (*list)[n].length=form.size_y; + (*list)[n].left=form.left; + (*list)[n].top=form.top; + (*list)[n].right=form.right; + (*list)[n].bottom=form.bottom; + + if (form.name_ptr) + { + unistr2_to_ascii((*list)[n].name, &(form.name), sizeof((*list)[n].name)-1); + } + +} + +/**************************************************************************** +update a form struct +****************************************************************************/ +void update_a_form(nt_forms_struct **list, FORM form, int count) +{ + int n=0; + fstring form_name; + unistr2_to_ascii(form_name, &(form.name), sizeof(form_name)-1); + + DEBUG(6, ("[%s]\n", form_name)); + for (n=0; n<count; n++) + { + DEBUGADD(6, ("n [%d]:[%s]\n", n, (*list)[n].name)); + if (!strncmp((*list)[n].name, form_name, strlen(form_name))) + break; + } + + if (n==count) return; + + (*list)[n].flag=form.flags; + (*list)[n].width=form.size_x; + (*list)[n].length=form.size_y; + (*list)[n].left=form.left; + (*list)[n].top=form.top; + (*list)[n].right=form.right; + (*list)[n].bottom=form.bottom; +} /**************************************************************************** get the nt drivers list -open the rectory and look-up the matching names +open the directory and look-up the matching names ****************************************************************************/ int get_ntdrivers(connection_struct *conn, fstring **list, char *architecture) { diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 8f5c85c158..c090239f38 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -471,6 +471,7 @@ void spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_st case 0x1: case 0x3: case 0x4: + case 0x7: prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size); prs_align(ps); break; @@ -1387,6 +1388,23 @@ static void spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER } } +/******************************************************************* + * read a uint8 buffer of size *size. + * allocate memory for it + * return a pointer to the allocated memory and the size + * return NULL and a size of 0 if the buffer is empty + * + * jfmxxxx: fix it to also write a buffer + ********************************************************************/ +void spoolss_io_free_buffer(BUFFER *buffer) +{ + DEBUG(8,("spoolss_io_free_buffer\n")); + + if (buffer->ptr != 0x0000) + { + free(buffer->data); + } +} /******************************************************************* * read a structure. @@ -3341,6 +3359,7 @@ void spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st case 0x1: case 0x3: case 0x4: + case 0x7: q_u->data=(uint8 *)malloc(q_u->max_len * sizeof(uint8)); prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len); prs_align(ps); @@ -3387,3 +3406,93 @@ void convert_specific_param(NT_PRINTER_PARAM **param, UNISTR2 value , uint32 typ DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len)); } + +/******************************************************************* +********************************************************************/ +static void spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_addform"); + depth++; + prs_align(ps); + + if (ptr!=0) + { + prs_uint32("flags", ps, depth, &(f->flags)); + prs_uint32("name_ptr", ps, depth, &(f->name_ptr)); + prs_uint32("size_x", ps, depth, &(f->size_x)); + prs_uint32("size_y", ps, depth, &(f->size_y)); + prs_uint32("left", ps, depth, &(f->left)); + prs_uint32("top", ps, depth, &(f->top)); + prs_uint32("right", ps, depth, &(f->right)); + prs_uint32("bottom", ps, depth, &(f->bottom)); + + smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth); + } +} + +/******************************************************************* +********************************************************************/ +void spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0; + prs_debug(ps, depth, desc, "spoolss_io_q_addform"); + depth++; + + prs_align(ps); + smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth); + prs_uint32("level", ps, depth, &(q_u->level)); + prs_uint32("level2", ps, depth, &(q_u->level2)); + + if (q_u->level==1) + { + prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); + spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + } +} + +/******************************************************************* +********************************************************************/ +void spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_addform"); + depth++; + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_u->status)); +} + +/******************************************************************* +********************************************************************/ +void spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0; + prs_debug(ps, depth, desc, "spoolss_io_q_setform"); + depth++; + + prs_align(ps); + smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth); + smb_io_unistr2("", &(q_u->name), True, ps, depth); + + prs_align(ps); + + prs_uint32("level", ps, depth, &(q_u->level)); + prs_uint32("level2", ps, depth, &(q_u->level2)); + + if (q_u->level==1) + { + prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); + spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + } +} + +/******************************************************************* +********************************************************************/ +void spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_setform"); + depth++; + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_u->status)); +} + diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 5b3ea4502a..c8df41a810 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -430,6 +430,7 @@ static void api_spoolss_open_printer(pipes_struct *p, prs_struct *data, prs_stru static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *type, uint32 *numeric_data, uint8 **data, uint32 *needed) { + int i; if (!strcmp(value, "BeepEnabled")) { @@ -492,8 +493,14 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *ty *type = 0x1; *data = (uint8 *)malloc( size*sizeof(uint8) ); ZERO_STRUCTP(*data); - make_unistr((UNISTR *)*data, directory); - *needed = 2*(strlen(directory)+1); + + /* it's done by hand ready to go on the wire */ + for (i=0; i<strlen(directory); i++) + { + (*data)[2*i]=directory[i]; + (*data)[2*i+1]='\0'; + } + *needed = 2*(strlen(directory)+1); return True; } @@ -503,7 +510,11 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *ty *type = 0x1; *data = (uint8 *)malloc( size*sizeof(uint8) ); ZERO_STRUCTP(*data); - make_unistr((UNISTR *)*data, directory); + for (i=0; i<strlen(directory); i++) + { + (*data)[2*i]=directory[i]; + (*data)[2*i+1]='\0'; + } *needed = 2*(strlen(directory)+1); return True; } @@ -1824,6 +1835,8 @@ static void api_spoolss_enumprinters(pipes_struct *p, prs_struct *data, spoolss_io_q_enumprinters("", &q_u, data, 0); spoolss_reply_enumprinters(&q_u, rdata, p->conn); + + spoolss_io_free_buffer(&(q_u.buffer)); } @@ -2124,6 +2137,8 @@ static void api_spoolss_getprinterdriver2(pipes_struct *p, prs_struct *data, spoolss_io_q_getprinterdriver2("", &q_u, data, 0); spoolss_reply_getprinterdriver2(&q_u, rdata); + + spoolss_io_free_buffer(&(q_u.buffer)); } /**************************************************************************** @@ -2599,6 +2614,8 @@ static void api_spoolss_addjob(pipes_struct *p, prs_struct *data, spoolss_io_q_addjob("", &q_u, data, 0); spoolss_reply_addjob(&q_u, rdata); + + spoolss_io_free_buffer(&(q_u.buffer)); } /**************************************************************************** @@ -2757,6 +2774,8 @@ static void api_spoolss_enumjobs(pipes_struct *p, prs_struct *data, spoolss_io_q_enumjobs("", &q_u, data, 0); spoolss_reply_enumjobs(&q_u, rdata, p->conn); + + spoolss_io_free_buffer(&(q_u.buffer)); } /**************************************************************************** @@ -2958,6 +2977,8 @@ static void api_spoolss_enumprinterdrivers(pipes_struct *p, prs_struct *data, spoolss_io_q_enumprinterdrivers("", &q_u, data, 0); spoolss_reply_enumprinterdrivers(&q_u, rdata, p->conn); + + spoolss_io_free_buffer(&(q_u.buffer)); } @@ -3033,8 +3054,12 @@ static void api_spoolss_enumforms(pipes_struct *p, prs_struct *data, spoolss_io_q_enumforms("", &q_u, data, 0); spoolss_reply_enumforms(&q_u, rdata); + + spoolss_io_free_buffer(&(q_u.buffer)); } +/**************************************************************************** +****************************************************************************/ static void fill_port_2(PORT_INFO_2 *port, char *name) { make_unistr(&(port->port_name), name); @@ -3101,6 +3126,8 @@ static void api_spoolss_enumports(pipes_struct *p, prs_struct *data, spoolss_io_q_enumports("", &q_u, data, 0); spoolss_reply_enumports(&q_u, rdata); + + spoolss_io_free_buffer(&(q_u.buffer)); } /**************************************************************************** @@ -3225,6 +3252,8 @@ static void api_spoolss_getprinterdriverdirectory(pipes_struct *p, prs_struct *d spoolss_io_q_getprinterdriverdir("", &q_u, data, 0); spoolss_reply_getprinterdriverdirectory(&q_u, rdata); + + spoolss_io_free_buffer(&(q_u.buffer)); } /**************************************************************************** @@ -3381,6 +3410,86 @@ static void api_spoolss_setprinterdata(pipes_struct *p, prs_struct *data, free(q_u.data); } +/**************************************************************************** +****************************************************************************/ +static void spoolss_reply_addform(SPOOL_Q_ADDFORM *q_u, prs_struct *rdata) +{ + SPOOL_R_ADDFORM r_u; + int pnum=0; + int count=0; + nt_forms_struct *list=NULL; + + DEBUG(5,("spoolss_reply_addform\n")); + + pnum = find_printer_index_by_hnd(&(q_u->handle)); + + if (OPEN_HANDLE(pnum)) + { + count=get_ntforms(&list); + + add_a_form(&list, q_u->form, count); + + write_ntforms(&list, count+1); + + free(list); + } + + r_u.status = 0x0; + spoolss_io_r_addform("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static void api_spoolss_addform(pipes_struct *p, prs_struct *data, + prs_struct *rdata) +{ + SPOOL_Q_ADDFORM q_u; + + spoolss_io_q_addform("", &q_u, data, 0); + + spoolss_reply_addform(&q_u, rdata); +} + + +/**************************************************************************** +****************************************************************************/ +static void spoolss_reply_setform(SPOOL_Q_SETFORM *q_u, prs_struct *rdata) +{ + SPOOL_R_SETFORM r_u; + int pnum=0; + int count=0; + nt_forms_struct *list=NULL; + + DEBUG(5,("spoolss_reply_setform\n")); + + pnum = find_printer_index_by_hnd(&(q_u->handle)); + + if (OPEN_HANDLE(pnum)) + { + count=get_ntforms(&list); + + update_a_form(&list, q_u->form, count); + + write_ntforms(&list, count); + + free(list); + } + r_u.status = 0x0; + spoolss_io_r_setform("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static void api_spoolss_setform(pipes_struct *p, prs_struct *data, + prs_struct *rdata) +{ + SPOOL_Q_SETFORM q_u; + + spoolss_io_q_setform("", &q_u, data, 0); + + spoolss_reply_setform(&q_u, rdata); +} + /******************************************************************* \pipe\spoolss commands ********************************************************************/ @@ -3413,6 +3522,8 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory }, {"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata }, {"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata }, + {"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform }, + {"SPOOLSS_SETFORM", SPOOLSS_SETFORM, api_spoolss_setform }, { NULL, 0, NULL } }; |