Fixed most memory leak and big-endian bug in the spoolss code.
authorJean-François Micouleau <jfm@samba.org>
Tue, 22 Jun 1999 18:42:10 +0000 (18:42 +0000)
committerJean-François Micouleau <jfm@samba.org>
Tue, 22 Jun 1999 18:42:10 +0000 (18:42 +0000)
Also added addform/setform rpc api calls. Now I can add/change forms from
the server property dialog box.

Jean Francois

source/include/proto.h
source/include/rpc_spoolss.h
source/printing/nt_printing.c
source/rpc_parse/parse_spoolss.c
source/rpc_server/srv_spoolss.c

index 41a68296d25017ca68d27806345e602bd933d0db..5ddcc0e6500429c82436b11c85890ad88d368275 100644 (file)
@@ -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  */
 
index f8e7efe81b30a2596d05cbba1710cc27d0be5ffd..8476ad76919aabaef42cc318f198689996b68c17 100755 (executable)
 #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"
index 76b9ee909d203ecda00b64daeac3f8515b3aec90..0757d08b8c250dfc144175f6c595281dc4e4772c 100644 (file)
@@ -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)
 {
index 8f5c85c158bbf75961b8afe63b3eab9e6d6fbece..c090239f385a7e21bcd6ca70f92d9472d2566b6b 100644 (file)
@@ -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));
+}
+
index 5b3ea4502a35ba02531fedf5588031da54a889fc..c8df41a810e7e3fe177c55ca3bfd049ba2df1407 100755 (executable)
@@ -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                                  }
 };