merge from cvs main of jean-francois' spoolss work.
authorLuke Leighton <lkcl@samba.org>
Mon, 3 Apr 2000 11:31:17 +0000 (11:31 +0000)
committerLuke Leighton <lkcl@samba.org>
Mon, 3 Apr 2000 11:31:17 +0000 (11:31 +0000)
source/include/lib_smb_proto.h
source/include/nt_printing.h
source/include/proto.h
source/include/rpc_parse_proto.h
source/include/rpc_spoolss.h
source/printing/nt_printing.c
source/rpc_parse/parse_prs.c
source/rpc_parse/parse_spoolss.c
source/rpc_server/srv_spoolss.c
source/spoolssd/srv_spoolss_nt.c

index 4cc879070561036948977301986bf141052b4fa5..c384f4098f25aa57b590daf8c85f5135047a2bde 100644 (file)
@@ -632,6 +632,7 @@ BOOL prs_append_data(prs_struct * ps, const char *data, int len);
 BOOL prs_add_data(prs_struct * ps, const char *data, int len);
 void prs_switch_type(prs_struct *ps, BOOL io);
 void prs_force_dynamic(prs_struct *ps);
+uint32 prs_data_size(prs_struct *ps);
 uint32 prs_offset(prs_struct *ps);
 BOOL prs_set_offset(prs_struct *ps, uint32 offset);
 void prs_mem_free(prs_struct *ps);
index 22c837c7481b1bedef27fff097db88ed71f7ceaa..7d4c4e9dd55a02ea343ac3fe7eacc47ea902573c 100644 (file)
@@ -1,3 +1,28 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB parameters and setup
+   Copyright (C) Andrew Tridgell              1992-2000,
+   Copyright (C) Jean Francois Micouleau      1998-2000.
+   
+   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
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef NT_PRINTING_H_
+#define NT_PRINTING_H_
+
 #define ORIENTATION      0x00000001L
 #define PAPERSIZE        0x00000002L
 #define PAPERLENGTH      0x00000004L
@@ -192,7 +217,6 @@ typedef struct nt_printer_info_level_2
        fstring sharename;
        fstring portname;
        fstring drivername;
-       fstring comment;
        fstring location;
        NT_DEVICEMODE *devmode;
        fstring sepfile;
@@ -202,6 +226,9 @@ typedef struct nt_printer_info_level_2
        NT_PRINTER_PARAM *specific;
        /* SEC_DESC_BUF *secdesc; */
        /* not used but ... and how ??? */
+       uint32 changeid;
+       uint32 c_setprinter;
+       time_t setuptime;       
 } NT_PRINTER_INFO_LEVEL_2;
 
 typedef struct nt_printer_info_level
@@ -235,3 +262,4 @@ typedef struct _form
        UNISTR2 name;
 } FORM;
 */
+#endif /* NT_PRINTING_H_ */
index 146e964c8b13d69121f35869d57d7a67657a255c..9b25b9b55cca1d3b5e8acc7e0048d23478b1df89 100644 (file)
@@ -930,6 +930,11 @@ const char *get_sid_name_use_str(uint32 sid_name_use);
 BOOL do_file_lock(int fd, int waitsecs, int type);
 BOOL file_lock(int fd, int type, int secs, int *plock_depth);
 BOOL file_unlock(int fd, int *plock_depth);
+uint32 map_lock_offset(uint32 high, uint32 low);
+SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format,
+                        BOOL *err);
+SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format,
+                         BOOL *err);
 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
 void *startfileent(char *pfile, char *s_readbuf, int bufsize,
                                int *file_lock_depth, BOOL update);
@@ -3784,6 +3789,7 @@ BOOL prs_append_data(prs_struct * ps, const char *data, int len);
 BOOL prs_add_data(prs_struct * ps, const char *data, int len);
 void prs_switch_type(prs_struct *ps, BOOL io);
 void prs_force_dynamic(prs_struct *ps);
+uint32 prs_data_size(prs_struct *ps);
 uint32 prs_offset(prs_struct *ps);
 BOOL prs_set_offset(prs_struct *ps, uint32 offset);
 void prs_mem_free(prs_struct *ps);
@@ -4752,10 +4758,6 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
               int dum_size, int dum_buffsize);
 int reply_setdir(connection_struct * conn, char *inbuf, char *outbuf,
                 int dum_size, int dum_buffsize);
-SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format,
-                        BOOL *err);
-SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format,
-                         BOOL *err);
 int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf,
                   int length, int bufsize);
 int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf,
@@ -4956,9 +4958,10 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le
                              uint32 *needed, uint32 *returned);
 uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
                           NEW_BUFFER *buffer, uint32 offered, uint32 *needed);
-uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, uint32 unknown,
+uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, 
+                               uint32 clientmajorversion, uint32 clientminorversion,
                                NEW_BUFFER *buffer, uint32 offered,
-                               uint32 *needed, uint32 *unknown0, uint32 *unknown1);
+                               uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion);
 uint32 _spoolss_startpageprinter(const POLICY_HND *handle);
 uint32 _spoolss_endpageprinter(const POLICY_HND *handle);
 uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
@@ -4996,7 +4999,7 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
 uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
                                const SPOOL_PRINTER_INFO_LEVEL *info,
                                uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
-                               uint32 user_switch, const  SPOOL_USER_CTR *user,
+                               uint32 user_switch, const SPOOL_USER_CTR *user,
                                POLICY_HND *handle);
 uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
                                uint32 level,
@@ -5008,7 +5011,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
                                uint32 in_value_len, uint32 in_data_len,
                                uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
                                uint32 *out_type,
-                               uint32 *out_max_data_len, uint8  **out_pdata, uint32 *out_data_len);
+                               uint32 *out_max_data_len, uint8  **data_out, uint32 *out_data_len);
 uint32 _spoolss_setprinterdata( const POLICY_HND *handle,
                                const UNISTR2 *value,
                                uint32 type,
index cd1f0a44fbc362c428a0d2618f4d401080861dcc..ab36786297b0dff1153aa43229816fd0e14c375a 100644 (file)
@@ -937,7 +937,7 @@ BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
 BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
                                      prs_struct *ps, int depth);
 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, 
-                                       uint32 access_required, fstring cli_name, fstring user_name);
+                                       uint32 access_required, fstring clientname, fstring user_name);
 BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth);
 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
@@ -999,6 +999,10 @@ uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info);
 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info);
 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
+BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
+                              const POLICY_HND *hnd, fstring architecture,
+                              uint32 level, uint32 clientmajor, uint32 clientminor,
+                              NEW_BUFFER *buffer, uint32 offered);
 BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth);
 BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, 
@@ -1008,6 +1012,8 @@ BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct
 BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, 
+                               NEW_BUFFER *buffer, uint32 offered);
 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
@@ -1032,6 +1038,7 @@ BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps,
 BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
 BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth);
 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth);
 BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
index e25eabe4412878c12fef3ffb899db9908c8d564f..0100fb007ef158dafaf974fce76379b794414c9b 100755 (executable)
 #define PRINTER_ENUM_NETWORK           0x00000040
 
 /* the flags of each printers */
+#define PRINTER_ENUM_UNKNOWN_8         0x00000008
 #define PRINTER_ENUM_EXPAND            0x00004000
 #define PRINTER_ENUM_CONTAINER         0x00008000
 #define PRINTER_ENUM_ICONMASK          0x00ff0000
@@ -711,35 +712,49 @@ typedef struct printer_info_0
        UNISTR printername;
        UNISTR servername;
        uint32 cjobs;
-       uint32 attributes;
-       uint32 unknown0;
-       uint32 unknown1;
-       uint32 unknown2;
-       uint32 unknown3;
-       uint32 unknown4;
-       uint32 unknown5;
-       uint32 unknown6;
-       uint16 majorversion;
-       uint16 buildversion;
+       uint32 total_jobs;
+       uint32 total_bytes;
+       
+       uint16 year;
+       uint16 month;
+       uint16 dayofweek;
+       uint16 day;
+       uint16 hour;
+       uint16 minute;
+       uint16 second;
+       uint16 milliseconds;
+
+       uint32 global_counter;
+       uint32 total_pages;
+
+       uint16 major_version;
+       uint16 build_version;
+
        uint32 unknown7;
        uint32 unknown8;
        uint32 unknown9;
-       uint32 unknown10;
+       uint32 session_counter;
        uint32 unknown11;
-       uint32 unknown12;
+       uint32 printer_errors;
        uint32 unknown13;
        uint32 unknown14;
        uint32 unknown15;
        uint32 unknown16;
-       uint32 unknown17;
+       uint32 change_id;
        uint32 unknown18;
        uint32 status;
        uint32 unknown20;
-       uint32 unknown21;
+       uint32 c_setprinter;
+
        uint16 unknown22;
-       uint32 unknown23;
-}
-PRINTER_INFO_0;
+       uint16 unknown23;
+       uint16 unknown24;
+       uint16 unknown25;
+       uint16 unknown26;
+       uint16 unknown27;
+       uint16 unknown28;
+       uint16 unknown29;
+} PRINTER_INFO_0;
 
 typedef struct printer_info_1
 {
@@ -789,6 +804,7 @@ SPOOL_Q_ENUMPRINTERS;
 
 typedef struct printer_info_ctr_info
 {
+       PRINTER_INFO_0 *printers_0;
        PRINTER_INFO_1 *printers_1;
        PRINTER_INFO_2 *printers_2;
 }
@@ -829,9 +845,7 @@ typedef struct spool_r_getprinter
        NEW_BUFFER *buffer;
        uint32 needed;
        uint32 status;
-
-}
-SPOOL_R_GETPRINTER;
+} SPOOL_R_GETPRINTER;
 
 struct s_notify_info_data_table
 {
@@ -839,16 +853,15 @@ struct s_notify_info_data_table
        uint16 field;
        char *name;
        uint32 size;
-       void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA * data,
-                   print_queue_struct * queue,
-                   NT_PRINTER_INFO_LEVEL * printer);
+       void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
+                   print_queue_struct *queue,
+                   NT_PRINTER_INFO_LEVEL *printer);
 };
 
 typedef struct driver_info_1
 {
        UNISTR name;
-}
-DRIVER_INFO_1;
+} DRIVER_INFO_1;
 
 typedef struct driver_info_2
 {
@@ -858,8 +871,7 @@ typedef struct driver_info_2
        UNISTR driverpath;
        UNISTR datafile;
        UNISTR configfile;
-}
-DRIVER_INFO_2;
+} DRIVER_INFO_2;
 
 typedef struct driver_info_3
 {
@@ -870,7 +882,7 @@ typedef struct driver_info_3
        UNISTR datafile;
        UNISTR configfile;
        UNISTR helpfile;
-       UNISTR **dependentfiles;
+       uint16 *dependentfiles;
        UNISTR monitorname;
        UNISTR defaultdatatype;
 }
@@ -878,16 +890,11 @@ DRIVER_INFO_3;
 
 typedef struct driver_info_info
 {
-       union
-       {
-               DRIVER_INFO_1 *info1;
-               DRIVER_INFO_2 *info2;
-               DRIVER_INFO_3 *info3;
-       }
-       driver;
-
+       DRIVER_INFO_1 *info1;
+       DRIVER_INFO_2 *info2;
+       DRIVER_INFO_3 *info3;
 }
-DRIVER_INFO;
+PRINTER_DRIVER_CTR;
 
 typedef struct spool_q_getprinterdriver2
 {
@@ -897,7 +904,8 @@ typedef struct spool_q_getprinterdriver2
        uint32 level;
        NEW_BUFFER *buffer;
        uint32 offered;
-       uint32 unknown;
+       uint32 clientmajorversion;
+       uint32 clientminorversion;
 }
 SPOOL_Q_GETPRINTERDRIVER2;
 
@@ -905,8 +913,8 @@ typedef struct spool_r_getprinterdriver2
 {
        NEW_BUFFER *buffer;
        uint32 needed;
-       uint32 unknown0;
-       uint32 unknown1;
+       uint32 servermajorversion;
+       uint32 serverminorversion;
        uint32 status;
 }
 SPOOL_R_GETPRINTERDRIVER2;
@@ -1180,6 +1188,17 @@ typedef struct spool_r_enumforms
 SPOOL_R_ENUMFORMS;
 
 
+typedef struct spool_printer_info_level_1
+{
+       uint32 flags;
+       uint32 description_ptr;
+       uint32 name_ptr;
+       uint32 comment_ptr;
+       UNISTR2 description;
+       UNISTR2 name;
+       UNISTR2 comment;        
+} SPOOL_PRINTER_INFO_LEVEL_1;
+
 typedef struct spool_printer_info_level_2
 {
        uint32 servername_ptr;
@@ -1222,6 +1241,7 @@ typedef struct spool_printer_info_level
 {
        uint32 level;
        uint32 info_ptr;
+       SPOOL_PRINTER_INFO_LEVEL_1 *info_1;
        SPOOL_PRINTER_INFO_LEVEL_2 *info_2;
 }
 SPOOL_PRINTER_INFO_LEVEL;
@@ -1525,7 +1545,6 @@ typedef struct spool_q_setprinterdata
        uint8 *data;
        uint32 real_len;
        uint32 numeric_data;
-
 }
 SPOOL_Q_SETPRINTERDATA;
 
@@ -1597,9 +1616,11 @@ typedef struct pjob_info_info
                JOB_INFO_1 *job_info_1;
                JOB_INFO_2 *job_info_2;
                void *info;
-       } job;
+       }
+       job;
 
-} PJOB_INFO;
+}
+PJOB_INFO;
 
 typedef struct spool_r_getjob
 {
index 88efba6563dfe163c3c8b834c8e5cc329b91648f..a2a8d728d9d246acd46b4e392a930610cc96481b 100644 (file)
@@ -1,3 +1,25 @@
+/* 
+ *  Unix SMB/Netbios implementation.
+ *  Version 1.9.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell              1992-2000,
+ *  Copyright (C) Jean François Micouleau      1998-2000.
+ *  
+ *  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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
 #include "includes.h"
 #include "nterr.h"
 
@@ -31,7 +53,7 @@ static BOOL parse_form_entry(char *line, nt_forms_struct *buf)
                count++;
        }
 
-       DEBUG(6,("Found [%d] tokens\n", count));
+       DEBUG(106,("Found [%d] tokens\n", count));
 
        StrnCpy(buf->name,tok[NAMETOK],sizeof(buf->name)-1);
        buf->flag=atoi(tok[FLAGTOK]);
@@ -65,7 +87,7 @@ int get_ntforms(nt_forms_struct **list)
 
        while ( fgets(line, sizeof(pstring), f) )
        {
-               DEBUG(5,("%s\n",line));
+               DEBUG(105,("%s\n",line));
                
                *list = Realloc(*list, sizeof(nt_forms_struct)*(total+1));
                if (! *list)
@@ -73,7 +95,7 @@ int get_ntforms(nt_forms_struct **list)
                        total = 0;
                        break;
                }
-               memset( (char *)&(*list)[total], 0,  sizeof(nt_forms_struct) );
+               memset( (char *)&(*list)[total], '\0', sizeof(nt_forms_struct) );
                if ( parse_form_entry(line, &(*list)[total] ) )
                {
                        total++;
@@ -82,7 +104,7 @@ int get_ntforms(nt_forms_struct **list)
        }    
        fclose(f);
 
-       DEBUG(4,("%d info lines on %d\n",total, grandtotal));
+       DEBUG(104,("%d info lines on %d\n",total, grandtotal));
 
        return(total);
 }
@@ -100,7 +122,7 @@ int write_ntforms(nt_forms_struct **list, int number)
 
        *line=0;
 
-       DEBUG(6,("write_ntforms\n"));
+       DEBUG(106,("write_ntforms\n"));
 
        if((f = sys_fopen(file, "w")) == NULL)
        {
@@ -115,11 +137,11 @@ int write_ntforms(nt_forms_struct **list, int number)
                       (*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));
+              DEBUGADD(107,("adding entry [%s]\n", (*list)[i].name));
        }
 
        fclose(f);
-       DEBUGADD(6,("closing file\n"));
+       DEBUGADD(106,("closing file\n"));
        return(total);
 }
 
@@ -145,7 +167,7 @@ void add_a_form(nt_forms_struct **list, const FORM *form, int *count)
        {
                if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
                {
-                       DEBUG(3, ("NT workaround, [%s] already exists\n", form_name));
+                       DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
                        update=True;
                }
        }
@@ -175,10 +197,10 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count)
        fstring form_name;
        unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
 
-       DEBUG(6, ("[%s]\n", form_name));
+       DEBUG(106, ("[%s]\n", form_name));
        for (n=0; n<count; n++)
        {
-               DEBUGADD(6, ("n [%d]:[%s]\n", n, (*list)[n].name));
+               DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
                if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
                        break;
        }
@@ -209,7 +231,7 @@ int get_ntdrivers(fstring **list, char *architecture)
        int match_len;
        int total=0;
 
-       DEBUG(5,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file()));
+       DEBUG(105,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file()));
        
        *list=NULL;
        dirp = opendir(lp_nt_drivers_file());
@@ -228,13 +250,13 @@ int get_ntdrivers(fstring **list, char *architecture)
        {
                if (strncmp(dpname, name_match, match_len)==0)
                {
-                       DEBUGADD(7,("Found: [%s]\n", dpname));
+                       DEBUGADD(107,("Found: [%s]\n", dpname));
                        
                        fstrcpy(driver_name, dpname+match_len);
                        all_string_sub(driver_name, "#", "/", 0);
                        *list = Realloc(*list, sizeof(fstring)*(total+1));
                        StrnCpy((*list)[total], driver_name, strlen(driver_name));
-                       DEBUGADD(6,("Added: [%s]\n", driver_name));             
+                       DEBUGADD(106,("Added: [%s]\n", driver_name));           
                        total++;
                }
        }
@@ -266,20 +288,20 @@ void get_short_archi(char *short_archi, char *long_archi)
        
        int i=-1;
 
-       DEBUG(7,("Getting architecture dependant directory\n"));
+       DEBUG(107,("Getting architecture dependant directory\n"));
        do {
                i++;
        } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
 
        if (archi_table[i].long_archi==NULL)
        {
-               DEBUGADD(7,("Unknown architecture [%s] !\n", long_archi));
+               DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
        }
        StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
 
-       DEBUGADD(8,("index: [%d]\n", i));
-       DEBUGADD(8,("long architecture: [%s]\n", long_archi));
-       DEBUGADD(8,("short architecture: [%s]\n", short_archi));
+       DEBUGADD(108,("index: [%d]\n", i));
+       DEBUGADD(108,("long architecture: [%s]\n", long_archi));
+       DEBUGADD(108,("short architecture: [%s]\n", short_archi));
 }
 
 /****************************************************************************
@@ -397,7 +419,7 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
                v=strncpyn(p, line, sizeof(p), ':');
                if (v==NULL)
                {
-                       DEBUG(1, ("malformed printer entry (no :)\n"));
+                       DEBUG(1, ("malformed printer driver entry (no :)\n"));
                        continue;
                }
                
@@ -444,7 +466,6 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
                        StrnCpy(dependentfiles[i], v, strlen(v) );
                        i++;
                }
-
        }
        
        free(line);
@@ -471,36 +492,32 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
        NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
        char **dependentfiles;  
        
-       DEBUG(6,("Dumping printer driver at level [%d]\n", level));
+       DEBUG(106,("Dumping printer driver at level [%d]\n", level));
        
        switch (level)
        {
                case 3: 
                {
                        if (driver.info_3 == NULL)
-                       {
-                               DEBUGADD(3,("NULL pointer, memory not alloced ?\n"));
                                success=5;
-                       }
-                       else
-                       {
+                       else {
                                info3=driver.info_3;
                        
-                               DEBUGADD(6,("version:[%d]\n",         info3->cversion));
-                               DEBUGADD(6,("name:[%s]\n",            info3->name));
-                               DEBUGADD(6,("environment:[%s]\n",     info3->environment));
-                               DEBUGADD(6,("driverpath:[%s]\n",      info3->driverpath));
-                               DEBUGADD(6,("datafile:[%s]\n",        info3->datafile));
-                               DEBUGADD(6,("configfile:[%s]\n",      info3->configfile));
-                               DEBUGADD(6,("helpfile:[%s]\n",        info3->helpfile));
-                               DEBUGADD(6,("monitorname:[%s]\n",     info3->monitorname));
-                               DEBUGADD(6,("defaultdatatype:[%s]\n", info3->defaultdatatype));
+                               DEBUGADD(106,("version:[%d]\n",         info3->cversion));
+                               DEBUGADD(106,("name:[%s]\n",            info3->name));
+                               DEBUGADD(106,("environment:[%s]\n",     info3->environment));
+                               DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
+                               DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
+                               DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
+                               DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
+                               DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
+                               DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
                                
                                dependentfiles=info3->dependentfiles;
        
                                while ( **dependentfiles != '\0' )
                                {
-                                       DEBUGADD(6,("dependentfile:[%s]\n", *dependentfiles));
+                                       DEBUGADD(106,("dependentfile:[%s]\n", *dependentfiles));
                                        dependentfiles++;
                                }
                                success=0;
@@ -619,6 +636,9 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
        fprintf(f, "status: %d\n", info->status);
        fprintf(f, "cjobs: %d\n", info->cjobs);
        fprintf(f, "averageppm: %d\n", info->averageppm);
+       fprintf(f, "changeid: %d\n", info->changeid);
+       fprintf(f, "c_setprinter: %d\n", info->c_setprinter);
+       fprintf(f, "setuptime: %d\n", (int)info->setuptime);
 
        /* 
         * in addprinter: no servername and the printer is the name
@@ -641,7 +661,6 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
        fprintf(f, "sharename: %s\n", info->sharename);
        fprintf(f, "portname: %s\n", info->portname);
        fprintf(f, "drivername: %s\n", info->drivername);
-       fprintf(f, "comment: %s\n", info->comment);
        fprintf(f, "location: %s\n", info->location);
        fprintf(f, "sepfile: %s\n", info->sepfile);
        fprintf(f, "printprocessor: %s\n", info->printprocessor);
@@ -676,7 +695,7 @@ static void dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v)
        char *tok[5];
        int count = 0;
 
-       DEBUG(5,("dissect_and_fill_a_param\n"));        
+       DEBUG(105,("dissect_and_fill_a_param\n"));      
                
        tok[count] = strtok(v,"#");
        count++;
@@ -693,7 +712,7 @@ static void dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v)
        strhex_to_str(param->data, 2*(param->data_len), tok[3]);                
        param->next=NULL;       
 
-       DEBUGADD(5,("value:[%s], len:[%d]\n", param->value, param->data_len));
+       DEBUGADD(105,("value:[%s], len:[%d]\n", param->value, param->data_len));
 }
 
 /****************************************************************************
@@ -703,10 +722,10 @@ used when reading from disk.
 ****************************************************************************/
 void dump_a_param(NT_PRINTER_PARAM *param)
 {
-       DEBUG(5,("dump_a_param\n"));
-       DEBUGADD(6,("value [%s]\n", param->value));
-       DEBUGADD(6,("type [%d]\n", param->type));
-       DEBUGADD(6,("data len [%d]\n", param->data_len));
+       DEBUG(105,("dump_a_param\n"));
+       DEBUGADD(106,("value [%s]\n", param->value));
+       DEBUGADD(106,("type [%d]\n", param->type));
+       DEBUGADD(106,("data len [%d]\n", param->data_len));
 }
 
 /****************************************************************************
@@ -715,7 +734,7 @@ BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *par
 {
        NT_PRINTER_PARAM *current;
        
-       DEBUG(8,("add_a_specific_param\n"));    
+       DEBUG(108,("add_a_specific_param\n"));  
 
        param->next=NULL;
        
@@ -749,10 +768,10 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_
        if ( !strcmp(current->value, param->value) && 
            (strlen(current->value)==strlen(param->value)) )
        {
-               DEBUG(9,("deleting first value\n"));
+               DEBUG(109,("deleting first value\n"));
                info_2->specific=current->next;
                free(current);
-               DEBUG(9,("deleted first value\n"));
+               DEBUG(109,("deleted first value\n"));
                return (True);
        }
 
@@ -763,10 +782,10 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_
                if (!strcmp(current->value, param->value) &&
                    strlen(current->value)==strlen(param->value) )
                {
-                       DEBUG(9,("deleting current value\n"));
+                       DEBUG(109,("deleting current value\n"));
                        previous->next=current->next;
                        free(current);
-                       DEBUG(9,("deleted current value\n"));
+                       DEBUG(109,("deleted current value\n"));
                        return(True);
                }
                
@@ -835,7 +854,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
                
                /* don't check if v==NULL as an empty arg is valid */
                
-               DEBUGADD(15, ("[%s]:[%s]\n", p, v));
+               DEBUGADD(115, ("[%s]:[%s]\n", p, v));
 
                /*
                 * The PRINTER_INFO_2 fields
@@ -865,6 +884,15 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
                if (!strncmp(p, "averageppm", strlen("averageppm")))
                        info->averageppm=atoi(v);
                
+               if (!strncmp(p, "changeid", strlen("changeid")))
+                       info->changeid=atoi(v);
+               
+               if (!strncmp(p, "c_setprinter", strlen("c_setprinter")))
+                       info->c_setprinter=atoi(v);
+               
+               if (!strncmp(p, "setuptime", strlen("setuptime")))
+                       info->setuptime=atoi(v);
+               
                if (!strncmp(p, "servername", strlen("servername")))
                        StrnCpy(info->servername, v, strlen(v));
 
@@ -880,9 +908,6 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
                if (!strncmp(p, "drivername", strlen("drivername")))
                        StrnCpy(info->drivername, v, strlen(v));
 
-               if (!strncmp(p, "comment", strlen("comment")))
-                       StrnCpy(info->comment, v, strlen(v));
-
                if (!strncmp(p, "location", strlen("location")))
                        StrnCpy(info->location, v, strlen(v));
 
@@ -1008,41 +1033,40 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
        uint32 success;
        NT_PRINTER_INFO_LEVEL_2 *info2;
        
-       DEBUG(6,("Dumping printer at level [%d]\n", level));
+       DEBUG(106,("Dumping printer at level [%d]\n", level));
        
        switch (level)
        {
                case 2: 
                {
                        if (printer.info_2 == NULL)
-                       {
-                               DEBUGADD(3,("NULL pointer, memory not alloced ?\n"));
                                success=5;
-                       }
                        else
                        {
                                info2=printer.info_2;
                        
-                               DEBUGADD(6,("attributes:[%d]\n",       info2->attributes));
-                               DEBUGADD(6,("priority:[%d]\n",         info2->priority));
-                               DEBUGADD(6,("default_priority:[%d]\n", info2->default_priority));
-                               DEBUGADD(6,("starttime:[%d]\n",        info2->starttime));
-                               DEBUGADD(6,("untiltime:[%d]\n",        info2->untiltime));
-                               DEBUGADD(6,("status:[%d]\n",           info2->status));
-                               DEBUGADD(6,("cjobs:[%d]\n",            info2->cjobs));
-                               DEBUGADD(6,("averageppm:[%d]\n",       info2->averageppm));
-
-                               DEBUGADD(6,("servername:[%s]\n",       info2->servername));
-                               DEBUGADD(6,("printername:[%s]\n",      info2->printername));
-                               DEBUGADD(6,("sharename:[%s]\n",        info2->sharename));
-                               DEBUGADD(6,("portname:[%s]\n",         info2->portname));
-                               DEBUGADD(6,("drivername:[%s]\n",       info2->drivername));
-                               DEBUGADD(6,("comment:[%s]\n",          info2->comment));
-                               DEBUGADD(6,("location:[%s]\n",         info2->location));
-                               DEBUGADD(6,("sepfile:[%s]\n",          info2->sepfile));
-                               DEBUGADD(6,("printprocessor:[%s]\n",   info2->printprocessor));
-                               DEBUGADD(6,("datatype:[%s]\n",         info2->datatype));
-                               DEBUGADD(6,("parameters:[%s]\n",       info2->parameters));
+                               DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
+                               DEBUGADD(106,("priority:[%d]\n", info2->priority));
+                               DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
+                               DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
+                               DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
+                               DEBUGADD(106,("status:[%d]\n", info2->status));
+                               DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
+                               DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
+                               DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
+                               DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
+                               DEBUGADD(106,("setuptime:[%d]\n", (int)info2->setuptime));
+
+                               DEBUGADD(106,("servername:[%s]\n", info2->servername));
+                               DEBUGADD(106,("printername:[%s]\n", info2->printername));
+                               DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
+                               DEBUGADD(106,("portname:[%s]\n", info2->portname));
+                               DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
+                               DEBUGADD(106,("location:[%s]\n", info2->location));
+                               DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
+                               DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
+                               DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
+                               DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
                                success=0;
                        }
                        break;
@@ -1114,7 +1138,7 @@ uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring share
 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
 {
        uint32 success;
-       DEBUG(4,("freeing a printer at level [%d]\n", level));
+       DEBUG(104,("freeing a printer at level [%d]\n", level));
        
        switch (level)
        {
@@ -1124,7 +1148,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
                        {
                                if ((printer.info_2)->devmode != NULL)
                                {
-                                       DEBUG(6,("deleting DEVMODE\n"));
+                                       DEBUG(106,("deleting DEVMODE\n"));
                                        if ((printer.info_2)->devmode->private !=NULL )
                                                free((printer.info_2)->devmode->private);
                                        free((printer.info_2)->devmode);
@@ -1140,7 +1164,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
                                        while ( param != NULL)
                                        {
                                                next_param=param->next;
-                                               DEBUG(6,("deleting param [%s]\n", param->value));
+                                               DEBUG(106,("deleting param [%s]\n", param->value));
                                                free(param->data);
                                                free(param);
                                                param=next_param;
@@ -1168,7 +1192,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
 {
        uint32 success;
-       DEBUG(4,("adding a printer at level [%d]\n", level));
+       DEBUG(104,("adding a printer at level [%d]\n", level));
        dump_a_printer_driver(driver, level);
        
        switch (level)
@@ -1272,17 +1296,16 @@ BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, ui
                i++;
        }
        
-       if (param != NULL)
-       {
-               /* exited because it exist */
-               *type=param->type;              
-               StrnCpy(value, param->value, sizeof(value)-1);
-               *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
-               memcpy(*data, param->data, param->data_len);
-               *len=param->data_len;
-               return (True);
-       }
-       return (False);
+       if (param == NULL)
+               return False;
+
+       /* exited because it exist */
+       *type=param->type;              
+       StrnCpy(value, param->value, sizeof(fstring)-1);
+       *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
+       memcpy(*data, param->data, param->data_len);
+       *len=param->data_len;
+       return True;
 }
 
 /****************************************************************************
@@ -1293,7 +1316,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
        /* right now that's enough ! */ 
        NT_PRINTER_PARAM *param;
        
-       DEBUG(5, ("get_specific_param\n"));
+       DEBUG(105, ("get_specific_param\n"));
        
        param=printer.info_2->specific;
                
@@ -1306,7 +1329,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
                param=param->next;
        }
        
-       DEBUG(6, ("found one param\n"));
+       DEBUG(106, ("found one param\n"));
        if (param != NULL)
        {
                /* exited because it exist */
@@ -1316,10 +1339,10 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
                memcpy(*data, param->data, param->data_len);
                *len=param->data_len;
 
-               DEBUG(6, ("exit of get_specific_param:true\n"));
+               DEBUG(106, ("exit of get_specific_param:true\n"));
                return (True);
        }
-       DEBUG(6, ("exit of get_specific_param:false\n"));
+       DEBUG(106, ("exit of get_specific_param:false\n"));
        return (False);
 }
 
@@ -1331,7 +1354,7 @@ void init_devicemode(NT_DEVICEMODE *nt_devmode)
  * should I init this ones ???
        nt_devmode->devicename
 */
-       safe_strcpy(nt_devmode->formname, "A4", sizeof(nt_devmode->formname)-1);
+       fstrcpy(nt_devmode->formname, "A4");
 
        nt_devmode->specversion      = 0x0401;
        nt_devmode->driverversion    = 0x0400;
index 214fc2d73c613ef7bb90453c9b33ac041c8bdf79..56c835b4bf57e0fa56cfdee7070198b530dc6533 100644 (file)
@@ -576,7 +576,14 @@ void prs_force_dynamic(prs_struct *ps)
 /*******************************************************************
  Fetch the current offset (external interface).
  ********************************************************************/
+uint32 prs_data_size(prs_struct *ps)
+{
+       return ps->data_size;
+}
 
+/*******************************************************************
+ Fetch the current offset (external interface).
+ ********************************************************************/
 uint32 prs_offset(prs_struct *ps)
 {
        return ps->offset;
@@ -585,7 +592,6 @@ uint32 prs_offset(prs_struct *ps)
 /*******************************************************************
  Set the current offset (external interface).
  ********************************************************************/
-
 BOOL prs_set_offset(prs_struct *ps, uint32 offset)
 {
        if(offset <= ps->offset) {
index e930014b245156c1d602a9ba8887b9f6a709d621..57853d6c152f9bafcb351d103ecf01ba73d0e8cf 100644 (file)
 #include "nterr.h"
 #include "rpc_parse.h"
 
-#undef prs_uint16
-#undef prs_uint32
-#undef prs_uint8s
-#undef prs_uint16s
-#undef prs_unistr
-#define prs_uint16 _prs_uint16
-#define prs_uint32 _prs_uint32
-#define prs_uint8s _prs_uint8s
-#define prs_uint16s _prs_uint16s
-#define prs_unistr _prs_unistr
-#define init_unistr2 make_unistr2
+#define TNG
+
+#ifdef TNG
+       #undef prs_uint16 
+       #undef prs_uint32
+       #undef prs_uint8s
+       #undef prs_uint16s
+       #undef prs_unistr
+       #undef prs_unistr2
+       #define prs_uint16 _prs_uint16
+       #define prs_uint32 _prs_uint32
+       #define prs_uint8s _prs_uint8s
+       #define prs_uint16s _prs_uint16s
+       #define prs_unistr _prs_unistr
+       #define prs_unistr2 _prs_unistr2
+       #define init_unistr2 make_unistr2
+       #define init_buf_unistr2 make_buf_unistr2
+#endif
 
 
 extern int DEBUGLEVEL;
@@ -59,14 +66,22 @@ This should be moved in a more generic lib.
 ********************************************************************/  
 static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
 {
-       prs_uint16("year", ps, depth, &(systime->year));
-       prs_uint16("month", ps, depth, &(systime->month));
-       prs_uint16("dayofweek", ps, depth, &(systime->dayofweek));
-       prs_uint16("day", ps, depth, &(systime->day));
-       prs_uint16("hour", ps, depth, &(systime->hour));
-       prs_uint16("minute", ps, depth, &(systime->minute));
-       prs_uint16("second", ps, depth, &(systime->second));
-       prs_uint16("milliseconds", ps, depth, &(systime->milliseconds));
+       if(!prs_uint16("year", ps, depth, &(systime->year)))
+               return False;
+       if(!prs_uint16("month", ps, depth, &(systime->month)))
+               return False;
+       if(!prs_uint16("dayofweek", ps, depth, &(systime->dayofweek)))
+               return False;
+       if(!prs_uint16("day", ps, depth, &(systime->day)))
+               return False;
+       if(!prs_uint16("hour", ps, depth, &(systime->hour)))
+               return False;
+       if(!prs_uint16("minute", ps, depth, &(systime->minute)))
+               return False;
+       if(!prs_uint16("second", ps, depth, &(systime->second)))
+               return False;
+       if(!prs_uint16("milliseconds", ps, depth, &(systime->milliseconds)))
+               return False;
 
        return True;
 }
@@ -97,15 +112,22 @@ static BOOL smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, in
        prs_debug(ps, depth, desc, "smb_io_doc_info_1");
        depth++;
  
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("p_docname",    ps, depth, &(info_1->p_docname));
-       prs_uint32("p_outputfile", ps, depth, &(info_1->p_outputfile));
-       prs_uint32("p_datatype",   ps, depth, &(info_1->p_datatype));
+       if(!prs_uint32("p_docname",    ps, depth, &(info_1->p_docname)))
+               return False;
+       if(!prs_uint32("p_outputfile", ps, depth, &(info_1->p_outputfile)))
+               return False;
+       if(!prs_uint32("p_datatype",   ps, depth, &(info_1->p_datatype)))
+               return False;
 
-       smb_io_unistr2("", &(info_1->docname),    info_1->p_docname,    ps, depth);
-       smb_io_unistr2("", &(info_1->outputfile), info_1->p_outputfile, ps, depth);
-       smb_io_unistr2("", &(info_1->datatype),   info_1->p_datatype,   ps, depth);
+       if(!smb_io_unistr2("", &(info_1->docname),    info_1->p_docname,    ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &(info_1->outputfile), info_1->p_outputfile, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &(info_1->datatype),   info_1->p_datatype,   ps, depth))
+               return False;
 
        return True;
 }
@@ -122,16 +144,20 @@ static BOOL smb_io_doc_info(char *desc, DOC_INFO *info, prs_struct *ps, int dept
        prs_debug(ps, depth, desc, "smb_io_doc_info");
        depth++;
  
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
         
-       prs_uint32("switch_value", ps, depth, &(info->switch_value));
+       if(!prs_uint32("switch_value", ps, depth, &(info->switch_value)))
+               return False;
        
-       prs_uint32("doc_info_X ptr", ps, depth, &(useless_ptr));
+       if(!prs_uint32("doc_info_X ptr", ps, depth, &(useless_ptr)))
+               return False;
 
        switch (info->switch_value)
        {
                case 1: 
-                       smb_io_doc_info_1("",&(info->doc_info_1), ps, depth);
+                       if(!smb_io_doc_info_1("",&(info->doc_info_1), ps, depth))
+                               return False;
                        break;
                case 2:
                        /*
@@ -164,11 +190,14 @@ static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_
        prs_debug(ps, depth, desc, "smb_io_doc_info_container");
        depth++;
  
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
         
-       prs_uint32("level", ps, depth, &(cont->level));
+       if(!prs_uint32("level", ps, depth, &(cont->level)))
+               return False;
        
-       smb_io_doc_info("",&(cont->docinfo), ps, depth);
+       if(!smb_io_doc_info("",&(cont->docinfo), ps, depth))
+               return False;
 
        return True;
 }
@@ -312,20 +341,28 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs
        
        isvalue=data->enc_type;
 
-       prs_align(ps);
-       prs_uint16("type",           ps, depth, &(data->type));
-       prs_uint16("field",          ps, depth, &(data->field));
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint16("type",           ps, depth, &(data->type)))
+               return False;
+       if(!prs_uint16("field",          ps, depth, &(data->field)))
+               return False;
        /*prs_align(ps);*/
 
-       prs_uint32("how many words", ps, depth, &how_many_words);
-       prs_uint32("id",             ps, depth, &(data->id));
-       prs_uint32("how many words", ps, depth, &how_many_words);
+       if(!prs_uint32("how many words", ps, depth, &how_many_words))
+               return False;
+       if(!prs_uint32("id",             ps, depth, &(data->id)))
+               return False;
+       if(!prs_uint32("how many words", ps, depth, &how_many_words))
+               return False;
        /*prs_align(ps);*/
 
        if (isvalue==True)
        {
-               prs_uint32("value[0]", ps, depth, &(data->notify_data.value[0]));
-               prs_uint32("value[1]", ps, depth, &(data->notify_data.value[1]));
+               if(!prs_uint32("value[0]", ps, depth, &(data->notify_data.value[0])))
+                       return False;
+               if(!prs_uint32("value[1]", ps, depth, &(data->notify_data.value[1])))
+                       return False;
                /*prs_align(ps);*/
        }
        else
@@ -333,8 +370,10 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs
                /* it's a string */
                /* length in ascii including \0 */
                x=2*(data->notify_data.data.length+1);
-               prs_uint32("string length", ps, depth, &x );
-               prs_uint32("pointer", ps, depth, &useless_ptr);
+               if(!prs_uint32("string length", ps, depth, &x ))
+                       return False;
+               if(!prs_uint32("pointer", ps, depth, &useless_ptr))
+                       return False;
                /*prs_align(ps);*/
        }
 
@@ -353,17 +392,22 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
        prs_debug(ps, depth, desc, "smb_io_notify_info_data");
        depth++;
        
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
        isvalue=data->enc_type;
 
        if (isvalue==False)
        {
                /* length of string in unicode include \0 */
                x=data->notify_data.data.length+1;
-               prs_uint32("string length", ps, depth, &x );
-               prs_uint16s(True,"string",ps,depth,data->notify_data.data.string,x);
+               if(!prs_uint32("string length", ps, depth, &x ))
+                       return False;
+               if(!prs_uint16s(True,"string",ps,depth,data->notify_data.data.string,x))
+                       return False;
        }
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
@@ -381,20 +425,26 @@ static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *
        if(!prs_align(ps))
                return False;
 
-       prs_uint32("count", ps, depth, &(info->count));
-       prs_uint32("version", ps, depth, &(info->version));
-       prs_uint32("flags", ps, depth, &(info->flags));
-       prs_uint32("count", ps, depth, &(info->count));
+       if(!prs_uint32("count", ps, depth, &(info->count)))
+               return False;
+       if(!prs_uint32("version", ps, depth, &(info->version)))
+               return False;
+       if(!prs_uint32("flags", ps, depth, &(info->flags)))
+               return False;
+       if(!prs_uint32("count", ps, depth, &(info->count)))
+               return False;
 
        for (i=0;i<info->count;i++)
        {
-               smb_io_notify_info_data(desc, &(info->data[i]), ps, depth);
+               if(!smb_io_notify_info_data(desc, &(info->data[i]), ps, depth))
+                       return False;
        }
 
        /* now do the strings at the end of the stream */       
        for (i=0;i<info->count;i++)
        {
-               smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth);
+               if(!smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth))
+                       return False;
        }
 
        return True;
@@ -550,6 +600,8 @@ static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE
        {
                if (UNMARSHALLING(ps)) {
                        devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8));
+                       if(devmode->private == NULL)
+                               return False;
                        DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra)); 
                }
                        
@@ -592,6 +644,8 @@ static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *p
        if (UNMARSHALLING(ps)) {
                DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
                dm_c->devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
+               if(dm_c->devmode == NULL)
+                       return False;
                ZERO_STRUCTP(dm_c->devmode);
        }
        
@@ -637,7 +691,7 @@ static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_stru
  * init a structure.
  ********************************************************************/
 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, 
-                                       uint32 access_required, fstring cli_name, fstring user_name)
+                                       uint32 access_required, fstring clientname, fstring user_name)
 {
        DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
        q_u->printername_ptr = (printername!=NULL)?1:0;
@@ -655,14 +709,14 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printe
        q_u->user_switch=1;
        q_u->user_ctr.level=1;
        q_u->user_ctr.ptr=1;
-       q_u->user_ctr.user1.size=strlen(cli_name)+strlen(user_name)+8;
-       q_u->user_ctr.user1.client_name_ptr = (cli_name!=NULL)?1:0;
+       q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+8;
+       q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
        q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
        q_u->user_ctr.user1.build=1381;
        q_u->user_ctr.user1.major=2;
        q_u->user_ctr.user1.minor=0;
        q_u->user_ctr.user1.processor=0;
-       init_unistr2(&(q_u->user_ctr.user1.client_name), cli_name, strlen(cli_name));
+       init_unistr2(&(q_u->user_ctr.user1.client_name), clientname, strlen(clientname));
        init_unistr2(&(q_u->user_ctr.user1.user_name), user_name, strlen(user_name));
        
        return True;
@@ -873,11 +927,14 @@ BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_
        prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
        
-       smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth);    
+       if(!smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth))
+               return False;
 
        return True;
 }
@@ -890,8 +947,10 @@ BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_
 {
        prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
        depth++;
-       prs_uint32("jobid", ps, depth, &(r_u->jobid));
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("jobid", ps, depth, &(r_u->jobid)))
+               return False;
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -907,9 +966,11 @@ BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_stru
        prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
 
        return True;
 }
@@ -922,7 +983,8 @@ BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_stru
 {
        prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
        depth++;
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -938,9 +1000,11 @@ BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, pr
        prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
 
        return True;
 }
@@ -953,7 +1017,8 @@ BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, pr
 {
        prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
        depth++;
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -969,9 +1034,11 @@ BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_st
        prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
 
        return True;
 }
@@ -984,7 +1051,8 @@ BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_st
 {
        prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
        depth++;
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -1000,18 +1068,26 @@ BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct
        prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
-       prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size));
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
+       if(!prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size)))
+               return False;
        
        if (q_u->buffer_size!=0)
        {
                q_u->buffer=(uint8 *)malloc(q_u->buffer_size*sizeof(uint8));
-               prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size);
+               if(q_u->buffer == NULL)
+                       return False;   
+               if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
+                       return False;
        }
-       prs_align(ps);
-       prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2));    
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2)))
+               return False;
 
        return True;
 }
@@ -1024,8 +1100,10 @@ BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct
 {
        prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
        depth++;
-       prs_uint32("buffer_written", ps, depth, &(r_u->buffer_written));
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("buffer_written", ps, depth, &(r_u->buffer_written)))
+               return False;
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -1148,6 +1226,14 @@ BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, in
        return True;
 }
 
+/*******************************************************************
+ * return the length of a uint16 (obvious, but the code is clean)
+ ********************************************************************/
+static uint32 size_of_uint16(uint16 *value)
+{
+       return (sizeof(*value));
+}
+
 /*******************************************************************
  * return the length of a uint32 (obvious, but the code is clean)
  ********************************************************************/
@@ -1155,7 +1241,6 @@ static uint32 size_of_uint32(uint32 *value)
 {
        return (sizeof(*value));
 }
-
 /*******************************************************************
  * return the length of a UNICODE string in number of char, includes:
  * - the leading zero
@@ -1181,7 +1266,7 @@ static uint32 size_of_device_mode(DEVICEMODE *devmode)
        if (devmode==NULL)
                return (4);
        else 
-               return (0xDC+4);
+               return (4+devmode->size+devmode->driverextra);
 }
 
 /*******************************************************************
@@ -1275,39 +1360,49 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR
 
 
 /*******************************************************************
- * write a array UNICODE strings and its relative pointer.
+ * write a array of UNICODE strings and its relative pointer.
  * used by 2 RPC structs
  ********************************************************************/
-static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR ***string)
+static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
 {
+       UNISTR chaine;
+       
        prs_struct *ps=&(buffer->prs);
        
        if (MARSHALLING(ps)) {
                uint32 struct_offset = prs_offset(ps);
                uint32 relative_offset;
-               int i=0;
-       
-               while ( (*string)[i]!=0x0000 )
-                       i++;
-               i--;
-
-               /* count the ending NULL of the array */
+               uint16 *p;
+               uint16 *q;
+               uint16 zero=0;
+               p=*string;
+               q=*string;
+               
+               /* first write the last 0 */
                buffer->string_at_end -= 2;
+               prs_set_offset(ps, buffer->string_at_end);
+
+               if(!prs_uint16("leading zero", ps, depth, &zero))
+                       return False;
 
-               /* jfm: FIXME: write a (uint16) 0 for the ending NULL */
-               
                do
-               {
-                       buffer->string_at_end -= 2*(str_len_uni((*string)[i])+1);
+               {       
+                       while (*q!=0)
+                               q++;
+
+                       memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
+
+                       buffer->string_at_end -= (q-p+1)*sizeof(uint16);
+
                        prs_set_offset(ps, buffer->string_at_end);
 
                        /* write the string */
-                       if (!spoolss_smb_io_unistr(desc, (*string)[i], ps, depth))
+                       if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
                                return False;
-               
-                       i--;
-               }
-               while (i>=0);
+                       q++;
+                       p=q;
+
+               } while (*p!=0); /* end on the last leading 0 */
                
                prs_set_offset(ps, struct_offset);
                
@@ -1318,22 +1413,32 @@ static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UN
        }
        else {
                uint32 old_offset;
+               uint16 *chaine2=NULL;
+               int l_chaine=0;
+               int l_chaine2=0;
                
+               *string=NULL;
+                               
                /* read the offset */
                if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
                        return False;
 
                old_offset = prs_offset(ps);
-               prs_set_offset(ps, buffer->string_at_end);
-
-               /* read the string */
-
-               /* jfm: FIXME: alloc memory and read all the strings until the string is NULL */
+               prs_set_offset(ps, buffer->string_at_end + buffer->struct_start);
+       
+               do {
+                       if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
+                               return False;
+                       
+                       l_chaine=str_len_uni(&chaine);
+                       chaine2=(uint16 *)Realloc(chaine2, (l_chaine2+l_chaine+1)*sizeof(uint16));
+                       memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
+                       l_chaine2+=l_chaine+1;
+               
+               } while(l_chaine!=0);
+               
+               *string=chaine2;
 
-/*
-               if (!spoolss_smb_io_unistr(desc, string, ps, depth))
-                       return False;
-*/
                prs_set_offset(ps, old_offset);
        }
        return True;
@@ -1409,26 +1514,36 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
        
        if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
                return False;
-       if(!prs_uint32("attributes", ps, depth, &info->attributes))
+       if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
+               return False;
+       if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
                return False;
 
-       if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
+       if(!prs_uint16("year", ps, depth, &info->year))
+               return False;
+       if(!prs_uint16("month", ps, depth, &info->month))
+               return False;
+       if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
+               return False;
+       if(!prs_uint16("day", ps, depth, &info->day))
                return False;
-       if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
+       if(!prs_uint16("hour", ps, depth, &info->hour))
                return False;
-       if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
+       if(!prs_uint16("minute", ps, depth, &info->minute))
                return False;
-       if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
+       if(!prs_uint16("second", ps, depth, &info->second))
                return False;
-       if(!prs_uint32("unknown4", ps, depth, &info->unknown4))
+       if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
                return False;
-       if(!prs_uint32("unknown5", ps, depth, &info->unknown5))
+
+       if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
                return False;
-       if(!prs_uint32("unknown6", ps, depth, &info->unknown6))
+       if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
                return False;
-       if(!prs_uint16("majorversion", ps, depth, &info->majorversion))
+
+       if(!prs_uint16("major_version", ps, depth, &info->major_version))
                return False;
-       if(!prs_uint16("buildversion", ps, depth, &info->buildversion))
+       if(!prs_uint16("build_version", ps, depth, &info->build_version))
                return False;
        if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
                return False;
@@ -1436,11 +1551,11 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
                return False;
        if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
                return False;
-       if(!prs_uint32("unknown10", ps, depth, &info->unknown10))
+       if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
                return False;
        if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
                return False;
-       if(!prs_uint32("unknown12", ps, depth, &info->unknown12))
+       if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
                return False;
        if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
                return False;
@@ -1450,7 +1565,7 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
                return False;
        if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
                return False;
-       if(!prs_uint32("unknown17", ps, depth, &info->unknown17))
+       if(!prs_uint32("change_id", ps, depth, &info->change_id))
                return False;
        if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
                return False;
@@ -1458,11 +1573,23 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
                return False;
        if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
                return False;
-       if(!prs_uint32("unknown21", ps, depth, &info->unknown21))
+       if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
                return False;
        if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
                return False;
-       if(!prs_uint32("unknown23", ps, depth, &info->unknown23))
+       if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
+               return False;
+       if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
+               return False;
+       if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
+               return False;
+       if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
+               return False;
+       if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
+               return False;
+       if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
+               return False;
+       if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
                return False;
 
        return True;
@@ -1908,7 +2035,7 @@ BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *
 
        buffer->struct_start=prs_offset(ps);
 
-       if(!new_smb_io_relstr("name", buffer, depth, &info->name))
+       if (!spoolss_smb_io_unistr(desc, &info->name, ps, depth))
                return False;
 
        return True;
@@ -2038,13 +2165,53 @@ uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
 {
        int size=0;
        
-       size+=24*4;
-       size+=6;
+       size+=size_of_relative_string( &info->printername );
+       size+=size_of_relative_string( &info->servername );
+
+       size+=size_of_uint32( &info->cjobs);
+       size+=size_of_uint32( &info->total_jobs);
+       size+=size_of_uint32( &info->total_bytes);
+
+       size+=size_of_uint16( &info->year);
+       size+=size_of_uint16( &info->month);
+       size+=size_of_uint16( &info->dayofweek);
+       size+=size_of_uint16( &info->day);
+       size+=size_of_uint16( &info->hour);
+       size+=size_of_uint16( &info->minute);
+       size+=size_of_uint16( &info->second);
+       size+=size_of_uint16( &info->milliseconds);
+
+       size+=size_of_uint32( &info->global_counter);
+       size+=size_of_uint32( &info->total_pages);
+
+       size+=size_of_uint16( &info->major_version);
+       size+=size_of_uint16( &info->build_version);
+
+       size+=size_of_uint32( &info->unknown7);
+       size+=size_of_uint32( &info->unknown8);
+       size+=size_of_uint32( &info->unknown9);
+       size+=size_of_uint32( &info->session_counter);
+       size+=size_of_uint32( &info->unknown11);
+       size+=size_of_uint32( &info->printer_errors);
+       size+=size_of_uint32( &info->unknown13);
+       size+=size_of_uint32( &info->unknown14);
+       size+=size_of_uint32( &info->unknown15);
+       size+=size_of_uint32( &info->unknown16);
+       size+=size_of_uint32( &info->change_id);
+       size+=size_of_uint32( &info->unknown18);
+       size+=size_of_uint32( &info->status);
+       size+=size_of_uint32( &info->unknown20);
+       size+=size_of_uint32( &info->c_setprinter);
+       
+       size+=size_of_uint16( &info->unknown22);
+       size+=size_of_uint16( &info->unknown23);
+       size+=size_of_uint16( &info->unknown24);
+       size+=size_of_uint16( &info->unknown25);
+       size+=size_of_uint16( &info->unknown26);
+       size+=size_of_uint16( &info->unknown27);
+       size+=size_of_uint16( &info->unknown28);
+       size+=size_of_uint16( &info->unknown29);
        
-       size+=size_of_uint32( &(info->attributes) );    
-       size+=size_of_relative_string( &(info->printername) );
-       size+=size_of_relative_string( &(info->servername) );
-
        return size;
 }
 
@@ -2071,30 +2238,30 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
        int size=0;
                
        size+=4;      /* the security descriptor */
-       size+=info->devmode->size+4; /* size of the devmode and the ptr */
-       size+=info->devmode->driverextra; /* if a devmode->private section exists, add its size */
        
-       size+=size_of_relative_string( &(info->servername) );
-       size+=size_of_relative_string( &(info->printername) );
-       size+=size_of_relative_string( &(info->sharename) );
-       size+=size_of_relative_string( &(info->portname) );
-       size+=size_of_relative_string( &(info->drivername) );
-       size+=size_of_relative_string( &(info->comment) );
-       size+=size_of_relative_string( &(info->location) );
+       size+=size_of_device_mode( info->devmode );
        
-       size+=size_of_relative_string( &(info->sepfile) );
-       size+=size_of_relative_string( &(info->printprocessor) );
-       size+=size_of_relative_string( &(info->datatype) );
-       size+=size_of_relative_string( &(info->parameters) );
-
-       size+=size_of_uint32( &(info->attributes) );
-       size+=size_of_uint32( &(info->priority) );
-       size+=size_of_uint32( &(info->defaultpriority) );
-       size+=size_of_uint32( &(info->starttime) );
-       size+=size_of_uint32( &(info->untiltime) );
-       size+=size_of_uint32( &(info->status) );
-       size+=size_of_uint32( &(info->cjobs) );
-       size+=size_of_uint32( &(info->averageppm) );    
+       size+=size_of_relative_string( &info->servername );
+       size+=size_of_relative_string( &info->printername );
+       size+=size_of_relative_string( &info->sharename );
+       size+=size_of_relative_string( &info->portname );
+       size+=size_of_relative_string( &info->drivername );
+       size+=size_of_relative_string( &info->comment );
+       size+=size_of_relative_string( &info->location );
+       
+       size+=size_of_relative_string( &info->sepfile );
+       size+=size_of_relative_string( &info->printprocessor );
+       size+=size_of_relative_string( &info->datatype );
+       size+=size_of_relative_string( &info->parameters );
+
+       size+=size_of_uint32( &info->attributes );
+       size+=size_of_uint32( &info->priority );
+       size+=size_of_uint32( &info->defaultpriority );
+       size+=size_of_uint32( &info->starttime );
+       size+=size_of_uint32( &info->untiltime );
+       size+=size_of_uint32( &info->status );
+       size+=size_of_uint32( &info->cjobs );
+       size+=size_of_uint32( &info->averageppm );      
        return size;
 }
 
@@ -2104,7 +2271,7 @@ return the size required by a struct in the stream
 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
 {
        int size=0;
-       size+=size_of_relative_string( &(info->name) );
+       size+=size_of_relative_string( &info->name );
 
        return size;
 }
@@ -2115,12 +2282,12 @@ return the size required by a struct in the stream
 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
 {
        int size=0;
-       size+=size_of_uint32( &(info->version) );       
-       size+=size_of_relative_string( &(info->name) );
-       size+=size_of_relative_string( &(info->architecture) );
-       size+=size_of_relative_string( &(info->driverpath) );
-       size+=size_of_relative_string( &(info->datafile) );
-       size+=size_of_relative_string( &(info->configfile) );
+       size+=size_of_uint32( &info->version ); 
+       size+=size_of_relative_string( &info->name );
+       size+=size_of_relative_string( &info->architecture );
+       size+=size_of_relative_string( &info->driverpath );
+       size+=size_of_relative_string( &info->datafile );
+       size+=size_of_relative_string( &info->configfile );
 
        return size;
 }
@@ -2131,26 +2298,24 @@ return the size required by a struct in the stream
 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
 {
        int size=0;
-       UNISTR **string;
+       uint16 *string;
        int i=0;
 
-       size+=size_of_uint32( &(info->version) );       
-       size+=size_of_relative_string( &(info->name) );
-       size+=size_of_relative_string( &(info->architecture) );
-       size+=size_of_relative_string( &(info->driverpath) );
-       size+=size_of_relative_string( &(info->datafile) );
-       size+=size_of_relative_string( &(info->configfile) );
-       size+=size_of_relative_string( &(info->helpfile) );
-       size+=size_of_relative_string( &(info->monitorname) );
-       size+=size_of_relative_string( &(info->defaultdatatype) );
+       size+=size_of_uint32( &info->version ); 
+       size+=size_of_relative_string( &info->name );
+       size+=size_of_relative_string( &info->architecture );
+       size+=size_of_relative_string( &info->driverpath );
+       size+=size_of_relative_string( &info->datafile );
+       size+=size_of_relative_string( &info->configfile );
+       size+=size_of_relative_string( &info->helpfile );
+       size+=size_of_relative_string( &info->monitorname );
+       size+=size_of_relative_string( &info->defaultdatatype );
        
        string=info->dependentfiles;
        
-       while ( (string)[i]!=0x0000 )
-       {
-               size+=2*(1+ str_len_uni( string[i] ) );
-               i++;
-       }
+       for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
+
+       size+=2*i;
        size+=6;
 
        return size;
@@ -2162,19 +2327,19 @@ return the size required by a struct in the stream
 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
 {
        int size=0;
-       size+=size_of_uint32( &(info->jobid) );
-       size+=size_of_relative_string( &(info->printername) );
-       size+=size_of_relative_string( &(info->machinename) );
-       size+=size_of_relative_string( &(info->username) );
-       size+=size_of_relative_string( &(info->document) );
-       size+=size_of_relative_string( &(info->datatype) );
-       size+=size_of_relative_string( &(info->text_status) );
-       size+=size_of_uint32( &(info->status) );
-       size+=size_of_uint32( &(info->priority) );
-       size+=size_of_uint32( &(info->position) );
-       size+=size_of_uint32( &(info->totalpages) );
-       size+=size_of_uint32( &(info->pagesprinted) );
-       size+=size_of_systemtime( &(info->submitted) );
+       size+=size_of_uint32( &info->jobid );
+       size+=size_of_relative_string( &info->printername );
+       size+=size_of_relative_string( &info->machinename );
+       size+=size_of_relative_string( &info->username );
+       size+=size_of_relative_string( &info->document );
+       size+=size_of_relative_string( &info->datatype );
+       size+=size_of_relative_string( &info->text_status );
+       size+=size_of_uint32( &info->status );
+       size+=size_of_uint32( &info->priority );
+       size+=size_of_uint32( &info->position );
+       size+=size_of_uint32( &info->totalpages );
+       size+=size_of_uint32( &info->pagesprinted );
+       size+=size_of_systemtime( &info->submitted );
 
        return size;
 }
@@ -2188,29 +2353,29 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
 
        size+=4; /* size of sec desc ptr */
 
-       size+=size_of_uint32( &(info->jobid) );
-       size+=size_of_relative_string( &(info->printername) );
-       size+=size_of_relative_string( &(info->machinename) );
-       size+=size_of_relative_string( &(info->username) );
-       size+=size_of_relative_string( &(info->document) );
-       size+=size_of_relative_string( &(info->notifyname) );
-       size+=size_of_relative_string( &(info->datatype) );
-       size+=size_of_relative_string( &(info->printprocessor) );
-       size+=size_of_relative_string( &(info->parameters) );
-       size+=size_of_relative_string( &(info->drivername) );
+       size+=size_of_uint32( &info->jobid );
+       size+=size_of_relative_string( &info->printername );
+       size+=size_of_relative_string( &info->machinename );
+       size+=size_of_relative_string( &info->username );
+       size+=size_of_relative_string( &info->document );
+       size+=size_of_relative_string( &info->notifyname );
+       size+=size_of_relative_string( &info->datatype );
+       size+=size_of_relative_string( &info->printprocessor );
+       size+=size_of_relative_string( &info->parameters );
+       size+=size_of_relative_string( &info->drivername );
        size+=size_of_device_mode( info->devmode );
-       size+=size_of_relative_string( &(info->text_status) );
+       size+=size_of_relative_string( &info->text_status );
 /*     SEC_DESC sec_desc;*/
-       size+=size_of_uint32( &(info->status) );
-       size+=size_of_uint32( &(info->priority) );
-       size+=size_of_uint32( &(info->position) );
-       size+=size_of_uint32( &(info->starttime) );
-       size+=size_of_uint32( &(info->untiltime) );
-       size+=size_of_uint32( &(info->totalpages) );
-       size+=size_of_uint32( &(info->size) );
-       size+=size_of_systemtime( &(info->submitted) );
-       size+=size_of_uint32( &(info->timeelapsed) );
-       size+=size_of_uint32( &(info->pagesprinted) );
+       size+=size_of_uint32( &info->status );
+       size+=size_of_uint32( &info->priority );
+       size+=size_of_uint32( &info->position );
+       size+=size_of_uint32( &info->starttime );
+       size+=size_of_uint32( &info->untiltime );
+       size+=size_of_uint32( &info->totalpages );
+       size+=size_of_uint32( &info->size );
+       size+=size_of_systemtime( &info->submitted );
+       size+=size_of_uint32( &info->timeelapsed );
+       size+=size_of_uint32( &info->pagesprinted );
 
        return size;
 }
@@ -2253,7 +2418,9 @@ uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
 {
        int size=0;
 
-       size+=size_of_relative_string( &info->name );
+       size=str_len_uni(&info->name);  /* the string length       */
+       size=size+1;                    /* add the leading zero    */
+       size=size*2;                    /* convert in char         */
 
        return size;
 }
@@ -2321,6 +2488,33 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
        return size;
 }
 
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
+                              const POLICY_HND *hnd, fstring architecture,
+                              uint32 level, uint32 clientmajor, uint32 clientminor,
+                              NEW_BUFFER *buffer, uint32 offered)
+{      
+       if (q_u == NULL)
+       {
+               return False;
+       }
+
+       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
+
+       init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
+
+       q_u->level=level;
+       q_u->clientmajorversion=clientmajor;
+       q_u->clientminorversion=clientminor;
+
+       q_u->buffer=buffer;
+       q_u->offered=offered;
+
+       return True;
+}
+
 /*******************************************************************
  * read a structure.
  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
@@ -2354,7 +2548,9 @@ BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u,
        if(!prs_uint32("offered", ps, depth, &q_u->offered))
                return False;
                
-       if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
+       if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
+               return False;
+       if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
                return False;
 
        return True;
@@ -2379,9 +2575,9 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
                return False;
        if (!prs_uint32("needed", ps, depth, &r_u->needed))
                return False;
-       if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
+       if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
                return False;
-       if (!prs_uint32("unknown1", ps, depth, &r_u->unknown1))
+       if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
                return False;           
        if (!prs_uint32("status", ps, depth, &r_u->status))
                return False;
@@ -2529,6 +2725,25 @@ BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps
        return True;
 }
 
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, 
+                               NEW_BUFFER *buffer, uint32 offered)
+{
+       if (q_u == NULL)
+       {
+               return False;
+       }
+       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
+
+       q_u->level=level;
+       q_u->buffer=buffer;
+       q_u->offered=offered;
+
+       return True;
+}
+
 /*******************************************************************
 ********************************************************************/  
 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
@@ -2536,9 +2751,11 @@ BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps
        prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -2564,8 +2781,10 @@ BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps
        if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
                return False;
        
-       prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer);
-       prs_uint32("security.data", ps, depth, &q_u->security.data);
+       if(!prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer))
+               return False;
+       if(!prs_uint32("security.data", ps, depth, &q_u->security.data))
+               return False;
        
        if(!prs_uint32("command", ps, depth, &q_u->command))
                return False;
@@ -2580,9 +2799,11 @@ BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
        prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_u->status));        
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -2595,9 +2816,11 @@ BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
        prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
 
        return True;
 }
@@ -2733,9 +2956,11 @@ BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *
        prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_u->status));        
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -2747,10 +2972,13 @@ BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *
        prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
-       prs_uint32("jobid", ps, depth, &(q_u->jobid));
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
+       if(!prs_uint32("jobid", ps, depth, &(q_u->jobid)))
+               return False;
 
        return True;
 }
@@ -2762,9 +2990,11 @@ BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int de
        prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_u->status));        
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -2776,16 +3006,21 @@ BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int de
        prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth);
-       prs_uint32("jobid", ps, depth, &(q_u->jobid));
+       if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
+       if(!prs_uint32("jobid", ps, depth, &(q_u->jobid)))
+               return False;
        /* 
         * level is usually 0. If (level!=0) then I'm in trouble !
         * I will try to generate setjob command with level!=0, one day.
         */
-       prs_uint32("level", ps, depth, &(q_u->level));
-       prs_uint32("command", ps, depth, &(q_u->command));
+       if(!prs_uint32("level", ps, depth, &(q_u->level)))
+               return False;
+       if(!prs_uint32("command", ps, depth, &(q_u->command)))
+               return False;
 
        return True;
 }
@@ -2976,6 +3211,36 @@ BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps,
        return True;
 }
 
+/*******************************************************************
+ Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
+********************************************************************/  
+BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
+{      
+       prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
+       depth++;
+               
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("flags", ps, depth, &il->flags))
+               return False;
+       if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
+               return False;
+       if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
+               return False;
+       if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
+               return False;
+               
+       if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
 ********************************************************************/  
@@ -3073,8 +3338,10 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
        
        /* if no struct inside just return */
        if (il->info_ptr==0) {
-               if (UNMARSHALLING(ps))
+               if (UNMARSHALLING(ps)) {
+                       il->info_1=NULL;
                        il->info_2=NULL;
+               }
                return True;
        }
                        
@@ -3089,9 +3356,21 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
                 * level 2 is used by addprinter
                 * and by setprinter when updating printer's info
                 */     
+               case 1:
+                       if (UNMARSHALLING(ps)) {
+                               il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_1));
+                               if(il->info_1 == NULL)
+                                       return False;
+                       }
+                       if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
+                               return False;
+                       break;          
                case 2:
-                       if (UNMARSHALLING(ps))
+                       if (UNMARSHALLING(ps)) {
                                il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
+                               if(il->info_2 == NULL)
+                                       return False;
+                       }
                        if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
                                return False;
                        break;          
@@ -3163,9 +3442,11 @@ BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct
        prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
        depth++;
        
-       smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth);
+       if(!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -3183,6 +3464,8 @@ BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_
        /* reading */
        if (UNMARSHALLING(ps)) {
                il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
+               if(il == NULL)
+                       return False;
                ZERO_STRUCTP(il);
                *q_u=il;
        }
@@ -3274,7 +3557,9 @@ BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar)
        src=buf5->buffer;
 
        string=(char *)malloc(sizeof(char)*buf5->buf_len);
-       
+       if(string == NULL)
+               return False;
+
        destend = string + buf5->buf_len;
        dest=string;
 
@@ -3285,6 +3570,8 @@ BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar)
                
        /* that ugly for the first one but that's working */
        array=(char **)Realloc(array, sizeof(char *)*(i+1));
+       if(array == NULL)
+               return False;
        array[i++]=string;
        
        while ( n < buf5->buf_len )
@@ -3292,6 +3579,8 @@ BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar)
                if ( *(string++) == '\0' )
                {
                        array=(char **)Realloc(array, sizeof(char *)*(i+1));
+                       if(array == NULL)
+                               return False;
                        array[i++]=string;                      
                }
                n++;
@@ -3315,10 +3604,11 @@ BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
        buffer->undoc=0;
        buffer->uni_str_len=buffer->uni_max_len;
        
-       prs_uint32("buffer_size", ps, depth, &(buffer->uni_max_len));
-
-       prs_unistr2(True, "buffer     ", ps, depth, buffer);
+       if(!prs_uint32("buffer_size", ps, depth, &(buffer->uni_max_len)))
+               return False;
 
+       if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
+               return False;
 
        return True;
 }
@@ -3342,7 +3632,8 @@ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LE
                
        switch (il->level) {
                case 3:
-                       spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth);
+                       if(!spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth))
+                               return False;
                        break;          
        }
 
@@ -3401,6 +3692,8 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
        if (*asc==NULL)
        {
                *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
+               if(*asc == NULL)
+                       return False;
                ZERO_STRUCTP(*asc);
        }       
 
@@ -3436,15 +3729,26 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
                               NT_PRINTER_INFO_LEVEL_2  **asc)
 {
        NT_PRINTER_INFO_LEVEL_2 *d;
+       NTTIME time_nt;
+       time_t time_unix;
        
        DEBUG(7,("Converting from UNICODE to ASCII\n"));
+       time_unix=time(NULL);
        
        if (*asc==NULL)
        {
                DEBUGADD(8,("allocating memory\n"));
 
                *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
+               if(*asc == NULL)
+                       return False;
                ZERO_STRUCTP(*asc);
+               
+               /* we allocate memory iff called from 
+                * addprinter(ex) so we can do one time stuff here.
+                */
+               (*asc)->setuptime=time_unix;
+
        }       
        DEBUGADD(8,("start converting\n"));
 
@@ -3458,17 +3762,21 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
        d->status=uni->status;
        d->cjobs=uni->cjobs;
 
-       unistr2_to_ascii(d->servername,     &(uni->servername),     sizeof(d->servername)-1);
-       unistr2_to_ascii(d->printername,    &(uni->printername),    sizeof(d->printername)-1);
-       unistr2_to_ascii(d->sharename,      &(uni->sharename),      sizeof(d->sharename)-1);
-       unistr2_to_ascii(d->portname,       &(uni->portname),       sizeof(d->portname)-1);
-       unistr2_to_ascii(d->drivername,     &(uni->drivername),     sizeof(d->drivername)-1);
-       unistr2_to_ascii(d->comment,        &(uni->comment),        sizeof(d->comment)-1);
-       unistr2_to_ascii(d->location,       &(uni->location),       sizeof(d->location)-1);
-       unistr2_to_ascii(d->sepfile,        &(uni->sepfile),        sizeof(d->sepfile)-1);
-       unistr2_to_ascii(d->printprocessor, &(uni->printprocessor), sizeof(d->printprocessor)-1);
-       unistr2_to_ascii(d->datatype,       &(uni->datatype),       sizeof(d->datatype)-1);
-       unistr2_to_ascii(d->parameters,     &(uni->parameters),     sizeof(d->parameters)-1);
+       unix_to_nt_time(&time_nt, time_unix);
+       d->changeid=time_nt.low;
+       
+       d->c_setprinter++;
+
+       unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
+       unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
+       unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
+       unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
+       unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
+       unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
+       unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
+       unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
+       unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
+       unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
 
        return True;
 }
@@ -3811,15 +4119,21 @@ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st
        prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
        depth++;
 
-       prs_align(ps);
-       smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth);
-       smb_io_unistr2("", &(q_u->value), True, ps, 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->value), True, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("type", ps, depth, &(q_u->type));
+       if(!prs_uint32("type", ps, depth, &(q_u->type)))
+               return False;
 
-       prs_uint32("max_len", ps, depth, &(q_u->max_len));      
+       if(!prs_uint32("max_len", ps, depth, &(q_u->max_len)))
+               return False;
 
        switch (q_u->type)
        {
@@ -3828,12 +4142,17 @@ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st
                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);
+                       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;
        }       
        
-       prs_uint32("real_len", ps, depth, &(q_u->real_len));
+       if(!prs_uint32("real_len", ps, depth, &(q_u->real_len)))
+               return False;
 
        return True;
 }
@@ -3845,8 +4164,10 @@ BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_st
        prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
        depth++;
 
-       prs_align(ps);
-       prs_uint32("status",     ps, depth, &(r_u->status));
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("status",     ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -3861,6 +4182,8 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
        if (*param == NULL)
        {
                *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
+               if(*param == NULL)
+                       return False;
                ZERO_STRUCTP(*param);
                DEBUGADD(6,("Allocated a new PARAM struct\n"));
        }
@@ -3873,6 +4196,8 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
        (*param)->data_len=len;
        
        (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
+       if((*param)->data == NULL)
+               return False;
                        
        memcpy((*param)->data, data, len);
                
@@ -3887,20 +4212,30 @@ static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps,
 {
        prs_debug(ps, depth, desc, "spoolss_io_addform");
        depth++;
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
        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);
+               if(!prs_uint32("flags",    ps, depth, &(f->flags)))
+                       return False;
+               if(!prs_uint32("name_ptr", ps, depth, &(f->name_ptr)))
+                       return False;
+               if(!prs_uint32("size_x",   ps, depth, &(f->size_x)))
+                       return False;
+               if(!prs_uint32("size_y",   ps, depth, &(f->size_y)))
+                       return False;
+               if(!prs_uint32("left",     ps, depth, &(f->left)))
+                       return False;
+               if(!prs_uint32("top",      ps, depth, &(f->top)))
+                       return False;
+               if(!prs_uint32("right",    ps, depth, &(f->right)))
+                       return False;
+               if(!prs_uint32("bottom",   ps, depth, &(f->bottom)))
+                       return False;
+
+               if(!smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth))
+                       return False;
        }
 
        return True;
@@ -3914,15 +4249,21 @@ BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int
        prs_debug(ps, depth, desc, "spoolss_io_q_addform");
        depth++;
 
-       prs_align(ps);
-       smb_io_pol_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(!prs_align(ps))
+               return False;
+       if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth))
+               return False;
+       if(!prs_uint32("level",  ps, depth, &(q_u->level)))
+               return False;
+       if(!prs_uint32("level2", ps, depth, &(q_u->level2)))
+               return False;
 
        if (q_u->level==1)
        {
-               prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
-               spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
+               if(!prs_uint32("useless_ptr", ps, depth, &(useless_ptr)))
+                       return False;
+               if(!spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth))
+                       return False;
        }
 
        return True;
@@ -3935,8 +4276,10 @@ BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int
        prs_debug(ps, depth, desc, "spoolss_io_r_addform");
        depth++;
 
-       prs_align(ps);
-       prs_uint32("status",    ps, depth, &(r_u->status));
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("status",        ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
@@ -3949,19 +4292,27 @@ BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int
        prs_debug(ps, depth, desc, "spoolss_io_q_setform");
        depth++;
 
-       prs_align(ps);
-       smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth);
-       smb_io_unistr2("", &(q_u->name), True, ps, 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->name), True, ps, depth))
+               return False;
              
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("level",  ps, depth, &(q_u->level));
-       prs_uint32("level2", ps, depth, &(q_u->level2));
+       if(!prs_uint32("level",  ps, depth, &(q_u->level)))
+               return False;
+       if(!prs_uint32("level2", ps, depth, &(q_u->level2)))
+               return False;
 
        if (q_u->level==1)
        {
-               prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
-               spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
+               if(!prs_uint32("useless_ptr", ps, depth, &(useless_ptr)))
+                       return False;
+               if(!spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth))
+                       return False;
        }
 
        return True;
@@ -3974,8 +4325,10 @@ BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int
        prs_debug(ps, depth, desc, "spoolss_io_r_setform");
        depth++;
 
-       prs_align(ps);
-       prs_uint32("status",    ps, depth, &(r_u->status));
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("status",        ps, depth, &(r_u->status)))
+               return False;
 
        return True;
 }
index 1b19a7b2a36293d1fd739a047c2db4fdef6d0d67..08925afabff6fc9d45131f707cd60b74b46743d2 100755 (executable)
@@ -320,9 +320,11 @@ static BOOL api_spoolss_getprinterdriver2(prs_struct *data, prs_struct *rdata)
 
        r_u.status =
                _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture,
-                                          q_u.level, q_u.unknown, r_u.buffer,
+                                          q_u.level, q_u.clientmajorversion,
+                                          q_u.clientminorversion, r_u.buffer,
                                           q_u.offered, &r_u.needed,
-                                          &r_u.unknown0, &r_u.unknown1);
+                                          &r_u.servermajorversion,
+                                          &r_u.serverminorversion);
 
        if (!spoolss_io_r_getprinterdriver2("", &r_u, rdata, 0))
        {
@@ -857,6 +859,19 @@ static BOOL api_spoolss_addprinterex(prs_struct *data, prs_struct *rdata)
                return False;
        }
 
+       if (q_u.info.info_ptr != 0)
+       {
+               switch (q_u.info.level)
+               {
+                       case 1:
+                               safe_free(q_u.info.info_1);
+                               break;
+                       case 2:
+                               safe_free(q_u.info.info_2);
+                               break;
+               }
+       }
+
        return True;
 }
 
index 5d8c3be6b719bd121dd7f857806e29b50d2e67f8..e99c7307625dc4e177d0154b0eaa92d7c24a31ae 100755 (executable)
@@ -76,7 +76,17 @@ typedef struct _Printer{
        } client;
 } Printer_entry;
 
+typedef struct _counter_printer_0 {
+       ubi_dlNode Next;
+       ubi_dlNode Prev;
+       
+       int snum;
+       uint32 counter;
+} counter_printer_0;
+
 static ubi_dlList Printer_list;
+static ubi_dlList counter_list;
+
 
 #define OPEN_HANDLE(pnum)    ((pnum!=NULL) && (pnum->open!=False))
 
@@ -86,6 +96,7 @@ static ubi_dlList Printer_list;
 void init_printer_hnd(void)
 {
        ubi_dlInitList(&Printer_list);
+       ubi_dlInitList(&counter_list);
 }
 
 /****************************************************************************
@@ -396,24 +407,24 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
        ps=&(buffer->prs);
 
        /* damn, I'm doing the reverse operation of prs_grow() :) */
-       if (buffer_size < ps->data_size)
+       if (buffer_size < prs_data_size(ps))
                extra_space=0;
        else    
-               extra_space = buffer_size - ps->data_size;
+               extra_space = buffer_size - prs_data_size(ps);
 
        /* 
         * save the offset and move to the end of the buffer
         * prs_grow() checks the extra_space against the offset 
         */
        old_offset=prs_offset(ps);      
-       prs_set_offset(ps, ps->data_size);
+       prs_set_offset(ps, prs_data_size(ps));
        
        if (!prs_grow(ps, extra_space))
                return False;
 
        prs_set_offset(ps, old_offset);
 
-       buffer->string_at_end=ps->data_size;
+       buffer->string_at_end=prs_data_size(ps);
 
        return True;
 }
@@ -433,7 +444,7 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
        clear_handle(handle);
        
        if (printername == NULL)
-               return NT_STATUS_ACCESS_DENIED;
+               return ERROR_INVALID_PRINTER_NAME;
 
        /* some sanity check because you can open a printer or a print server */
        /* aka: \\server\printer or \\server */
@@ -447,12 +458,12 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
        
        if (!set_printer_hnd_printertype(handle, name)) {
                close_printer_handle(handle);
-               return NT_STATUS_ACCESS_DENIED;
+               return ERROR_INVALID_PRINTER_NAME;
        }
        
        if (!set_printer_hnd_printername(handle, name)) {
                close_printer_handle(handle);
-               return NT_STATUS_ACCESS_DENIED;
+               return ERROR_INVALID_PRINTER_NAME;
        }
 
 /*
@@ -467,7 +478,7 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
        
        if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
                close_printer_handle(handle);
-               return NT_STATUS_ACCESS_DENIED;
+               return ERROR_ACCESS_DENIED;
        }
                
        return NT_STATUS_NO_PROBLEMO;
@@ -661,25 +672,32 @@ static BOOL getprinterdata_printer(const POLICY_HND *handle,
        
        DEBUG(5,("getprinterdata_printer\n"));
 
-       if (OPEN_HANDLE(Printer))
-       {
+       if (!OPEN_HANDLE(Printer))
+               return False;
+
                get_printer_snum(handle, &snum);                
                get_a_printer(&printer, 2, lp_servicename(snum));
                
-               if (get_specific_param(printer, 2, value, &idata, type, &len)) 
-               {
-                       *data  = (uint8 *)malloc( (len>in_size)?len:in_size *sizeof(uint8) );
-                       memset(*data, 0, sizeof(uint8)*len);
-                       memcpy(*data, idata, (len>in_size)?len:in_size);
+       if (!get_specific_param(printer, 2, value, &idata, type, &len)) {
+               free_a_printer(printer, 2);
+               return False;
+       }
+
+       DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
+
+       *data  = (uint8 *)malloc( in_size *sizeof(uint8) );
+       memset(*data, 0, in_size *sizeof(uint8));
+       /* copy the min(in_size, len) */
+       memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
+
                        *needed = len;
                        
-                       if (idata) free(idata);
-                       return (True);
-               }
+       DEBUG(5,("getprinterdata_printer:copy done\n"));
+                       
                free_a_printer(printer, 2);
-       }
+       safe_free(idata);
 
-       return (False);
+       return True;
 }      
 
 /********************************************************************
@@ -724,9 +742,10 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename,
                found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
 
        if (found==False) {
+               DEBUG(5, ("value not found, allocating %d\n", *out_size));
                /* reply this param doesn't exist */
-               *data=(uint8 *)malloc(4*sizeof(uint8));
-               memset(*data, 0x0, 4);
+               *data=(uint8 *)malloc(*out_size*sizeof(uint8));
+               memset(*data, 0x0, *out_size*sizeof(uint8));
                return ERROR_INVALID_PARAMETER;
        }
        
@@ -980,7 +999,7 @@ static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_
        memset(&status, 0, sizeof(status));
        count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &q, &status);
        data->notify_data.value[0]=(uint32) status.status;
-       if (q) free(q);
+       safe_free(q);
 }
 
 /*******************************************************************
@@ -993,7 +1012,7 @@ static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_q
 
        memset(&status, 0, sizeof(status));
        data->notify_data.value[0]=get_printqueue(snum, NULL, UID_FIELD_INVALID, &q, &status);
-       if (q) free(q);
+       safe_free(q);
 }
 
 /*******************************************************************
@@ -1497,17 +1516,45 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
        pstring chaine;
        int count;
        NT_PRINTER_INFO_LEVEL ntprinter;
+       counter_printer_0 *session_counter;
+       uint32 global_counter;
+       struct tm *t;
        
        print_queue_struct *queue=NULL;
        print_status_struct status;
+       
        memset(&status, 0, sizeof(status));     
 
        if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
-       {
-               return (False);
-       }
+               return False;
 
        count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status);
+
+       /* check if we already have a counter for this printer */       
+       session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
+
+       for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
+               if (session_counter->snum == snum)
+                       break;
+       }
+
+       /* it's the first time, add it to the list */
+       if (session_counter==NULL) {
+               session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0));
+               ZERO_STRUCTP(session_counter);
+               session_counter->snum=snum;
+               session_counter->counter=0;
+               ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
+       }
+       
+       /* increment it */
+       session_counter->counter++;
+       
+       /* JFM:
+        * the global_counter should be stored in a TDB as it's common to all the clients
+        * and should be zeroed on samba startup
+        */
+       global_counter=session_counter->counter;
        
        /* the description and the name are of the form \\server\share */
        slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter.info_2->printername);
@@ -1518,35 +1565,47 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
        init_unistr(&(printer->servername), chaine);
        
        printer->cjobs = count;
-       printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
-                             | PRINTER_ATTRIBUTE_NETWORK  \
-                             | PRINTER_ATTRIBUTE_RAW_ONLY ;
-       printer->unknown0     = 0x1; /* pointer */
-       printer->unknown1     = 0x000A07CE; /* don't known */
-       printer->unknown2     = 0x00020005;
-       printer->unknown3     = 0x0006000D;
-       printer->unknown4     = 0x02180026;
-       printer->unknown5     = 0x09;
-       printer->unknown6     = 0x36;
-       printer->majorversion = 0x0004; /* NT 4 */
-       printer->buildversion = 0x0565; /* build 1381 */
+       printer->total_jobs = 0;
+       printer->total_bytes = 0;
+
+       t=gmtime(&ntprinter.info_2->setuptime);
+
+       printer->year = t->tm_year+1900;
+       printer->month = t->tm_mon+1;
+       printer->dayofweek = t->tm_wday;
+       printer->day = t->tm_mday;
+       printer->hour = t->tm_hour;
+       printer->minute = t->tm_min;
+       printer->second = t->tm_sec;
+       printer->milliseconds = 0;
+
+       printer->global_counter = global_counter;
+       printer->total_pages = 0;
+       printer->major_version = 0x0004;        /* NT 4 */
+       printer->build_version = 0x0565;        /* build 1381 */
        printer->unknown7     = 0x1;
        printer->unknown8     = 0x0;
        printer->unknown9     = 0x2;
-       printer->unknown10    = 0x3;
+       printer->session_counter = session_counter->counter;
        printer->unknown11    = 0x0;
-       printer->unknown12    = 0x0;
+       printer->printer_errors = 0x0;          /* number of print failure */
        printer->unknown13    = 0x0;
        printer->unknown14    = 0x1;
        printer->unknown15    = 0x024a; /*586 Pentium ? */
        printer->unknown16    = 0x0;
-       printer->unknown17    = 0x423ed444; /* CacheChangeID */
+       printer->change_id = ntprinter.info_2->changeid; /* ChangeID in milliseconds*/
        printer->unknown18    = 0x0;
        printer->status       = status.status;
        printer->unknown20    = 0x0;
-       printer->unknown21    = 0x0648;
+       printer->c_setprinter = ntprinter.info_2->c_setprinter; /* how many times setprinter has been called */
        printer->unknown22    = 0x0;
-       printer->unknown23    = 0x5;
+       printer->unknown23 = 0x6;               /* 6  ???*/
+       printer->unknown24 = 0;                 /* unknown 24 to 26 are always 0 */
+       printer->unknown25 = 0;
+       printer->unknown26 = 0;
+       printer->unknown27 = 0;
+       printer->unknown28 = 0;
+       printer->unknown29 = 0;
 
        safe_free(queue);
 
@@ -1558,35 +1617,29 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
  * construct_printer_info_1
  * fill a printer_info_1 struct
  ********************************************************************/
-static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer, int snum, pstring servername)
+static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum)
 {
        pstring chaine;
        pstring chaine2;
        NT_PRINTER_INFO_LEVEL ntprinter;
        
        if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
-       {
-               return (False);
-       }
-       
-       printer->flags=PRINTER_ENUM_ICON8;
+               return False;
 
-       /* the description and the name are of the form \\server\share */
+       printer->flags=flags;
 
-       snprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername,
-                                                           ntprinter.info_2->printername,
-                                                           ntprinter.info_2->drivername,
-                                                           lp_comment(snum));
-       init_unistr(&(printer->description), chaine);
+       snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter.info_2->printername,
+               ntprinter.info_2->drivername, lp_comment(snum));
        
-       snprintf(chaine2,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername);
-       init_unistr(&(printer->name), chaine2);
+       snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter.info_2->printername);
        
-       init_unistr(&(printer->comment), lp_comment(snum));
+       init_unistr(&printer->description, chaine);
+       init_unistr(&printer->name, chaine2);   
+       init_unistr(&printer->comment, lp_comment(snum));
        
        free_a_printer(ntprinter, 2);
 
-       return (True);
+       return True;
 }
 
 /****************************************************************************
@@ -1653,9 +1706,11 @@ static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername)
  * construct_printer_info_2
  * fill a printer_info_2 struct
  ********************************************************************/
-static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring servername)
+static BOOL construct_printer_info_2(pstring servername, PRINTER_INFO_2 *printer, int snum)
 {
        pstring chaine;
+       pstring chaine2;
+       pstring sl;
        int count;
        DEVICEMODE *devmode;
        NT_PRINTER_INFO_LEVEL ntprinter;
@@ -1663,33 +1718,36 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring
        print_queue_struct *queue=NULL;
        print_status_struct status;
        memset(&status, 0, sizeof(status));     
-       count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status);
 
        if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
-       {
-               return (False);
-       }       
+               return False;
 
-       snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername);
-       init_unistr(&(printer->servername), chaine);                    /* servername*/
+       ZERO_STRUCT(status);            
+       count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status);
        
-       snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername);
-       init_unistr(&(printer->printername), chaine);                   /* printername*/
+       snprintf(chaine, sizeof(chaine)-1, "%s", servername);
 
-       init_unistr(&(printer->sharename),      lp_servicename(snum));  /* sharename */
+       if (strlen(servername)!=0)
+               fstrcpy(sl, "\\");
+       else
+               fstrcpy(sl, '\0');
 
-       init_unistr(&(printer->portname),       lp_servicename(snum));          /* port */      
-       init_unistr(&(printer->drivername),     ntprinter.info_2->drivername);  /* drivername */
+       snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter.info_2->printername);
                
-       init_unistr(&(printer->comment),        ntprinter.info_2->comment);     /* comment */   
-       init_unistr(&(printer->location),       ntprinter.info_2->location);    /* location */  
-       init_unistr(&(printer->sepfile),        ntprinter.info_2->sepfile);     /* separator file */
-       init_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */
-       init_unistr(&(printer->datatype),       ntprinter.info_2->datatype);    /* datatype */  
-       init_unistr(&(printer->parameters),     ntprinter.info_2->parameters);  /* parameters (of print processor) */   
+       init_unistr(&printer->servername, chaine);                              /* servername*/
+       init_unistr(&printer->printername, chaine2);                            /* printername*/
+       init_unistr(&printer->sharename, lp_servicename(snum));                 /* sharename */
+       init_unistr(&printer->portname, lp_servicename(snum));                  /* port */      
+       init_unistr(&printer->drivername, ntprinter.info_2->drivername);        /* drivername */
+       init_unistr(&printer->comment, lp_comment(snum));                       /* comment */   
+       init_unistr(&printer->location, ntprinter.info_2->location);            /* location */  
+       init_unistr(&printer->sepfile, ntprinter.info_2->sepfile);              /* separator file */
+       init_unistr(&printer->printprocessor, ntprinter.info_2->printprocessor);/* print processor */
+       init_unistr(&printer->datatype, ntprinter.info_2->datatype);            /* datatype */  
+       init_unistr(&printer->parameters, ntprinter.info_2->parameters);        /* parameters (of print processor) */   
 
        printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
-                             | PRINTER_ATTRIBUTE_NETWORK  \
+                             | PRINTER_ATTRIBUTE_LOCAL  \
                              | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
 
        printer->priority        = ntprinter.info_2->priority;          /* priority */  
@@ -1707,79 +1765,38 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring
        
        safe_free(queue);
        free_a_printer(ntprinter, 2);
-       return (True);
-}
-
-/********************************************************************
- * enum_printer_info_1
- * glue between spoolss_enumprinters and construct_printer_info_1
- ********************************************************************/
-static BOOL get_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number)
-{
-       pstring servername;
-
-       *printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
-       DEBUG(4,("Allocated memory for ONE PRINTER_INFO_1 at [%p]\n", *printer));       
-       pstrcpy(servername, global_myname);
-       if (!construct_printer_info_1(*printer, snum, servername)) {
-               free(*printer);
-               return False;
-       }
-       else
                return True;
 }
 
 /********************************************************************
- * enum_printer_info_2
- * glue between spoolss_enumprinters and construct_printer_info_2
- ********************************************************************/
-static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number)
-{
-       pstring servername;
-
-       *printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));
-       DEBUG(4,("Allocated memory for ONE PRINTER_INFO_2 at [%p]\n", *printer));       
-       pstrcpy(servername, global_myname);
-       if (!construct_printer_info_2(*printer, snum, servername))
-       {
-               free(*printer);
-               return (False);
-       }
-       else
-       {
-               return (True);
-       }
-}
-
-/********************************************************************
- * spoolss_enumprinters
- *
- * called from api_spoolss_enumprinters (see this to understand)
+ Spoolss_enumprinters.
  ********************************************************************/
-static BOOL enum_printer_info_1(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
-       PRINTER_INFO_1 *printer=NULL;
-DEBUG(1,("enum_printer_info_1\n"));
+       PRINTER_INFO_1 *printers=NULL;
+       PRINTER_INFO_1 current_prt;
+       
+       DEBUG(4,("enum_all_printers_info_1\n"));        
+
        for (snum=0; snum<n_services; snum++) {
                if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
                        DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
                
-                       /*
-                               JFM: here we should check the name
-                       
-                        */
-                               
-                       if (get_printer_info_1(&printer , snum, *returned) )                    
+                       if (construct_printer_info_1(server, flags, &current_prt, snum)) {
+                               printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1));
+                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));             
+                               memcpy(&(printers[*returned]), &current_prt, sizeof(PRINTER_INFO_1));
                                (*returned)++;
                }
        }
+       }
        
        /* check the required size. */  
        for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_1(printer);
+               (*needed) += spoolss_size_printer_info_1(&(printers[i]));
 
        if (!alloc_buffer_size(buffer, *needed))
                return ERROR_INSUFFICIENT_BUFFER;
@@ -1787,9 +1804,10 @@ DEBUG(1,("enum_printer_info_1\n"));
        /* fill the buffer with the structures */
 
        for (i=0; i<*returned; i++)
-               new_smb_io_printer_info_1("", buffer, printer, 0);      
+               new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);       
        
        /* clear memory */
+       safe_free(printers);
 
        if (*needed > offered) {
                *returned=0;
@@ -1800,49 +1818,87 @@ DEBUG(1,("enum_printer_info_1\n"));
 }
 
 /********************************************************************
Spoolss_enumprinters.
-********************************************************************/
-static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
enum_all_printers_info_1_local.
+*********************************************************************/
+static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
-       int snum;
-       int i;
-       int n_services=lp_numservices();
-       PRINTER_INFO_1 *printers=NULL;
-       PRINTER_INFO_1 current_prt;
-       pstring servername;
-       
-       DEBUG(4,("enum_all_printers_info_1\n"));
+       fstring temp;
+       DEBUG(4,("enum_all_printers_info_1_local\n"));  
        
-       pstrcpy(servername, global_myname);
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, global_myname);
 
-       for (snum=0; snum<n_services; snum++) {
-               if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
-                       DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
+       if (!strcmp(name, temp)) {
+               fstrcat(temp, "\\");
+               return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+       }
+       else
+               return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+}
                                
-                       if (construct_printer_info_1(&current_prt, snum, servername))
+/********************************************************************
+ enum_all_printers_info_1_name.
+*********************************************************************/
+static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
                        {
-                               printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1));
-                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));             
-                               memcpy(&(printers[*returned]), &current_prt, sizeof(PRINTER_INFO_1));
-                               (*returned)++;
-                       }
+       fstring temp;
+       DEBUG(4,("enum_all_printers_info_1_name\n"));   
+       
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, global_myname);
+
+       if (!strcmp(name, temp)) {
+               fstrcat(temp, "\\");
+               return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
                }
+       else
+               return ERROR_INVALID_NAME;
        }
                
+/********************************************************************
+ enum_all_printers_info_1_remote.
+*********************************************************************/
+static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+{
+       PRINTER_INFO_1 *printer;
+       fstring printername;
+       fstring desc;
+       fstring comment;
+       DEBUG(4,("enum_all_printers_info_1_remote\n")); 
+
+       /* JFM: currently it's more a place holder than anything else.
+        * In the spooler world there is a notion of server registration.
+        * the print servers are registring (sp ?) on the PDC (in the same domain)
+        * 
+        * We should have a TDB here. The registration is done thru an undocumented RPC call.
+        */
+       
+       printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
+
+       *returned=1;
+       
+       snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);               
+       snprintf(desc, sizeof(desc)-1,"%s", global_myname);
+       snprintf(comment, sizeof(comment)-1, "Logged on Domain");
+
+       init_unistr(&printer->description, desc);
+       init_unistr(&printer->name, printername);       
+       init_unistr(&printer->comment, comment);
+       printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
+               
        /* check the required size. */  
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_1(&(printers[i]));
+       *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
-
+       }
 
        /* fill the buffer with the structures */
-
-       for (i=0; i<*returned; i++)
-               new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);       
+       new_smb_io_printer_info_1("", buffer, printer, 0);      
 
        /* clear memory */
+       safe_free(printer);
 
        if (*needed > offered) {
                *returned=0;
@@ -1852,46 +1908,69 @@ static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32
                return NT_STATUS_NO_PROBLEMO;
 }
 
+/********************************************************************
+ enum_all_printers_info_1_network.
+*********************************************************************/
+static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+{
+       fstring temp;
+       DEBUG(4,("enum_all_printers_info_1_network\n"));        
+       
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, global_myname);
+       fstrcat(temp, "\\");
+       return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
+}
+
 /********************************************************************
  * api_spoolss_enumprinters
  *
  * called from api_spoolss_enumprinters (see this to understand)
  ********************************************************************/
-static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
-       PRINTER_INFO_2 **printers=NULL;
+       PRINTER_INFO_2 *printers=NULL;
+       PRINTER_INFO_2 current_prt;
 
        for (snum=0; snum<n_services; snum++) {
                if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
-               
                        DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
                        
-                       printers=Realloc(printers, ((*returned)+1)*sizeof(PRINTER_INFO_2 *));
-                                               
-                       DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2 pointers\n", (*returned)+1));                        
-
-                       if (get_printer_info_2( &(printers[*returned]), snum, *returned) )
+                       if (construct_printer_info_2(servername, &current_prt, snum)) {
+                               printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2));
+                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));             
+                               memcpy(&(printers[*returned]), &current_prt, sizeof(PRINTER_INFO_2));
                                (*returned)++;
                }
        }
+       }
        
        /* check the required size. */  
        for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_2(printers[i]);
-
-       DEBUG(4,("we need [%d] bytes\n", *needed));
+               (*needed) += spoolss_size_printer_info_2(&(printers[i]));
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               for (i=0; i<*returned; i++) {
+                       safe_free(printers[i].devmode->private);
+                       safe_free(printers[i].devmode);
+               }
+               safe_free(printers);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
-               new_smb_io_printer_info_2("", buffer, printers[i], 0);  
+               new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);       
        
        /* clear memory */
+       for (i=0; i<*returned; i++) {
+               safe_free(printers[i].devmode->private);
+               safe_free(printers[i].devmode);
+       }
+       safe_free(printers);
 
        if (*needed > offered) {
                *returned=0;
@@ -1908,20 +1987,21 @@ static uint32 enumprinters_level1( uint32 flags, fstring name,
                                 NEW_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
-       if (flags && PRINTER_ENUM_NETWORK)
-               return enum_all_printers_info_1(buffer, offered, needed, returned);
+       /* Not all the flags are equals */
        
-       if (flags && PRINTER_ENUM_NAME) {
-               if (*name=='\0')
-                       return enum_all_printers_info_1(buffer, offered, needed, returned);
-               else
-                       return enum_printer_info_1(name, buffer, offered, needed, returned);
-       }
+       if (flags & PRINTER_ENUM_LOCAL)
+               return enum_all_printers_info_1_local(name, buffer, offered, needed, returned);
        
-       if (flags && PRINTER_ENUM_REMOTE)
-               return enum_all_printers_info_1(buffer, offered, needed, returned);
+       if (flags & PRINTER_ENUM_NAME)
+               return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
 
-       return NT_STATUS_INVALID_LEVEL;
+       if (flags & PRINTER_ENUM_REMOTE)
+               return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
+
+       if (flags & PRINTER_ENUM_NETWORK)
+               return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
+
+       return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
 }
 
 /********************************************************************
@@ -1931,7 +2011,29 @@ static uint32 enumprinters_level2( uint32 flags, fstring servername,
                                 NEW_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
-       return enum_all_printers_info_2(buffer, offered, needed, returned);
+       fstring temp;
+       
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, global_myname);
+
+       if (flags & PRINTER_ENUM_LOCAL) {
+               if (!strcmp(servername, temp))
+                       return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
+               else
+                       return enum_all_printers_info_2("", buffer, offered, needed, returned);
+       }
+
+       if (flags & PRINTER_ENUM_NAME) {
+               if (!strcmp(servername, temp))
+                       return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
+               else
+                       return ERROR_INVALID_NAME;
+       }
+
+       if (flags & PRINTER_ENUM_REMOTE)
+               return ERROR_INVALID_LEVEL;
+
+       return NT_STATUS_NO_PROBLEMO;
 }
 
 /********************************************************************
@@ -1975,6 +2077,7 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le
         */
 
        unistr2_to_ascii(name, servername, sizeof(name)-1);
+       strupper(name);
 
        switch (level) {
        case 1:
@@ -2006,8 +2109,10 @@ static uint32 getprinter_level_0(pstring servername, int snum, NEW_BUFFER *buffe
        /* check the required size. */  
        *needed += spoolss_size_printer_info_0(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_0("", buffer, printer, 0);      
@@ -2029,13 +2134,15 @@ static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffe
        PRINTER_INFO_1 *printer=NULL;
 
        printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1));
-       construct_printer_info_1(printer, snum, servername);
+       construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_1("", buffer, printer, 0);      
@@ -2055,20 +2162,28 @@ static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffe
 static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_2 *printer=NULL;
+       fstring temp;
 
        printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));        
-       construct_printer_info_2(printer, snum, servername);
+       
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, servername);
+       construct_printer_info_2(temp, printer, snum);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_2(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_2("", buffer, printer, 0);      
        
        /* clear memory */
+       safe_free(printer->devmode->private);
+       safe_free(printer->devmode);
        safe_free(printer);
 
        if (*needed > offered) {
@@ -2091,9 +2206,7 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
        pstrcpy(servername, global_myname);
 
        if (!get_printer_snum(handle, &snum))
-       {
                return NT_STATUS_INVALID_HANDLE;
-       }
 
        switch (level) {
        case 0:
@@ -2106,7 +2219,7 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
                return getprinter_level_2(servername,snum, buffer, offered, needed);
                break;
        default:
-               return NT_STATUS_INVALID_LEVEL;
+               return ERROR_INVALID_LEVEL;
                break;
        }
 }      
@@ -2177,8 +2290,7 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info,
  * construct_printer_driver_info_2
  * fill a printer_info_2 struct
  ********************************************************************/
-static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, 
-                                            pstring servername, fstring architecture)
+static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, pstring servername, fstring architecture)
 {
        NT_PRINTER_INFO_LEVEL printer;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -2194,36 +2306,30 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum,
 
 /********************************************************************
  * copy a strings array and convert to UNICODE
+ *
+ * convert an array of ascii string to a UNICODE string
  ********************************************************************/
-static void init_unistr_array(UNISTR ***uni_array, char **char_array, char *where)
+static void init_unistr_array(uint16 **uni_array, char **char_array, char *where)
 {
        int i=0;
+       int j=0;
        char *v;
        pstring line;
 
        DEBUG(6,("init_unistr_array\n"));
+       *uni_array=NULL;
 
-       for (v=char_array[i]; *v!='\0'; v=char_array[i])
-       {
-               DEBUGADD(6,("i:%d:", i));
-               DEBUGADD(6,("%s:%d:", v, strlen(v)));
-       
-               *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1));
-               DEBUGADD(7,("realloc:[%p],", *uni_array));
-                       
-               (*uni_array)[i]=(UNISTR *)malloc( sizeof(UNISTR) );
-               DEBUGADD(7,("alloc:[%p],", (*uni_array)[i]));
-
+       for (v=char_array[i]; *v!='\0'; v=char_array[i]) {
                snprintf(line, sizeof(line)-1, "%s%s", where, v);
-               init_unistr( (*uni_array)[i], line );
-               DEBUGADD(7,("copy\n"));
-                       
+               DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
+               *uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16));
+               ascii_to_unistr( *uni_array+j, line , strlen(line));
+               j+=strlen(line)+1;                      
                i++;
        }
-       DEBUGADD(7,("last one\n"));
        
-       *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1));
-       (*uni_array)[i]=0x0000;
+       (*uni_array)[j]=0x0000;
+       
        DEBUGADD(6,("last one:done\n"));
 }
 
@@ -2302,8 +2408,10 @@ static uint32 getprinterdriver2_level1(pstring servername, pstring architecture,
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(info);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_driver_info_1("", buffer, info, 0);  
@@ -2311,9 +2419,8 @@ static uint32 getprinterdriver2_level1(pstring servername, pstring architecture,
        /* clear memory */
        safe_free(info);
 
-       if (*needed > offered) {
+       if (*needed > offered)
                return ERROR_INSUFFICIENT_BUFFER;
-       }
        else
                return NT_STATUS_NO_PROBLEMO;
 }
@@ -2331,8 +2438,10 @@ static uint32 getprinterdriver2_level2(pstring servername, pstring architecture,
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_2(info);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(info);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_driver_info_2("", buffer, info, 0);  
@@ -2340,9 +2449,8 @@ static uint32 getprinterdriver2_level2(pstring servername, pstring architecture,
        /* clear memory */
        safe_free(info);
 
-       if (*needed > offered) {
+       if (*needed > offered)
                return ERROR_INSUFFICIENT_BUFFER;
-       }
        else
                return NT_STATUS_NO_PROBLEMO;
 }
@@ -2360,27 +2468,30 @@ static uint32 getprinterdriver2_level3(pstring servername, pstring architecture,
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_3(info);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(info);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_driver_info_3("", buffer, info, 0);  
 
        /* clear memory */
+       safe_free(info->dependentfiles);
        safe_free(info);
 
-       if (*needed > offered) {
+       if (*needed > offered)
                return ERROR_INSUFFICIENT_BUFFER;
-       }
        else
                return NT_STATUS_NO_PROBLEMO;
 }
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, uint32 unknown,
+uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, 
+                               uint32 clientmajorversion, uint32 clientminorversion,
                                NEW_BUFFER *buffer, uint32 offered,
-                               uint32 *needed, uint32 *unknown0, uint32 *unknown1)
+                               uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion)
 {
        pstring servername;
        fstring architecture;
@@ -2389,16 +2500,14 @@ uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_a
        DEBUG(4,("_spoolss_getprinterdriver2\n"));
 
        *needed=0;
-       *unknown0=0;
-       *unknown1=0;
+       *servermajorversion=0;
+       *serverminorversion=0;
 
        pstrcpy(servername, global_myname);
        unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
 
        if (!get_printer_snum(handle, &snum))
-       {
                return NT_STATUS_INVALID_HANDLE;
-       }
 
        switch (level) {
        case 1:
@@ -2490,7 +2599,7 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
                if (strcmp(datatype, "RAW") != 0)
                {
                        (*jobid)=0;
-                       return STATUS_1804;
+                       return ERROR_INVALID_DATATYPE;
                }               
        }                
        
@@ -2507,7 +2616,7 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
        slprintf(tempname,sizeof(tempname)-1, "%s/smb_print.XXXXXX",lp_pathname(snum));  
        pstrcpy(fname, (char *)mktemp(tempname));
 
-       fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
+       fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR );
        DEBUG(4,("Temp spool file created: [%s]\n", fname));
 
        Printer->current_jobid=fd;
@@ -2767,9 +2876,10 @@ uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
                case 2:
                        return update_printer(handle, level, info, devmode_ctr.devmode);
                        break;
+               default:
+                       return ERROR_INVALID_LEVEL;
+                       break;
        }
-
-       return NT_STATUS_INVALID_INFO_CLASS;
 }
 
 /****************************************************************************
@@ -3093,27 +3203,31 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri
                free_a_printer_driver(driver, 3);
        }
        
+       safe_free(list);
+       
        /* check the required size. */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d]'s size\n",i));
                *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
        }
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(driver_info_1);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the form structures */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d] to buffer\n",i));
                new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
        }
 
-       safe_free(list);
+       safe_free(driver_info_1);
 
-       if (*needed > offered)
+       if (*needed > offered) {
+               *returned=0;
                return ERROR_INSUFFICIENT_BUFFER;
+       }
        else
                return NT_STATUS_NO_PROBLEMO;
 }
@@ -3134,27 +3248,31 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri
                free_a_printer_driver(driver, 3);
        }
        
+       safe_free(list);
+       
        /* check the required size. */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d]'s size\n",i));
                *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
        }
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(driver_info_2);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the form structures */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d] to buffer\n",i));
                new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
        }
 
-       safe_free(list);
+       safe_free(driver_info_2);
 
-       if (*needed > offered)
+       if (*needed > offered) {
+               *returned=0;
                return ERROR_INSUFFICIENT_BUFFER;
+       }
        else
                return NT_STATUS_NO_PROBLEMO;
 }
@@ -3175,27 +3293,34 @@ static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstri
                free_a_printer_driver(driver, 3);
        }
        
+       safe_free(list);
+       
        /* check the required size. */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d]'s size\n",i));
                *needed += spoolss_size_printer_driver_info_3(&(driver_info_3[i]));
        }
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(driver_info_3);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the form structures */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding form [%d] to buffer\n",i));
                new_smb_io_printer_driver_info_3("", buffer, &(driver_info_3[i]), 0);
        }
 
-       safe_free(list);
+       for (i=0; i<*returned; i++)
+               safe_free(driver_info_3[i].dependentfiles);
 
-       if (*needed > offered)
+       safe_free(driver_info_3);
+       
+       if (*needed > offered) {
+               *returned=0;
                return ERROR_INSUFFICIENT_BUFFER;
+       }
        else
                return NT_STATUS_NO_PROBLEMO;
 }
@@ -3235,7 +3360,7 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32
                return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned);
                break;
        default:
-               return NT_STATUS_INVALID_INFO_CLASS;
+               return ERROR_INVALID_LEVEL;
                break;
        }
 }
@@ -3277,41 +3402,44 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level,
                forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1));
 
                /* construct the list of form structures */
-               for (i=0; i<*numofforms; i++)
-               {
+               for (i=0; i<*numofforms; i++) {
                        DEBUGADD(6,("Filling form number [%d]\n",i));
                        fill_form_1(&(forms_1[i]), &(list[i]), i);
                }
 
+               safe_free(list);
+
                /* check the required size. */
-               for (i=0; i<*numofforms; i++)
-               {
+               for (i=0; i<*numofforms; i++) {
                        DEBUGADD(6,("adding form [%d]'s size\n",i));
                        buffer_size += spoolss_size_form_1(&(forms_1[i]));
                }
 
                *needed=buffer_size;            
                
-               if (!alloc_buffer_size(buffer, buffer_size))
+               if (!alloc_buffer_size(buffer, buffer_size)){
+                       safe_free(forms_1);
                        return ERROR_INSUFFICIENT_BUFFER;
+               }
 
                /* fill the buffer with the form structures */
-               for (i=0; i<*numofforms; i++)
-               {
+               for (i=0; i<*numofforms; i++) {
                        DEBUGADD(6,("adding form [%d] to buffer\n",i));
                        new_smb_io_form_1("", buffer, &(forms_1[i]), 0);
                }
 
-               safe_free(list);
+               safe_free(forms_1);
 
-               if (*needed > offered)
+               if (*needed > offered) {
+                       *numofforms=0;
                        return ERROR_INSUFFICIENT_BUFFER;
+               }
                else
                        return NT_STATUS_NO_PROBLEMO;
                        
        default:
                safe_free(list);
-               return NT_STATUS_INVALID_INFO_CLASS;
+               return ERROR_INVALID_LEVEL;
        }
 
 }
@@ -3352,8 +3480,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
 
        ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) );
        
-       for (snum=0; snum<n_services; snum++)
-       {
+       for (snum=0; snum<n_services; snum++) {
                if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
                        DEBUGADD(6,("Filling port number [%d]\n", i));
                        fill_port_1(&(ports[i]), lp_servicename(snum));
@@ -3362,18 +3489,18 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
        }
 
        /* check the required size. */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding port [%d]'s size\n", i));
                *needed += spoolss_size_port_info_1(&(ports[i]));
        }
                
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(ports);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the ports structures */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding port [%d] to buffer\n", i));
                new_smb_io_port_1("", buffer, &(ports[i]), 0);
        }
@@ -3406,8 +3533,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
 
        ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) );
        
-       for (snum=0; snum<n_services; snum++)
-       {
+       for (snum=0; snum<n_services; snum++) {
                if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
                        DEBUGADD(6,("Filling port number [%d]\n", i));
                        fill_port_2(&(ports[i]), lp_servicename(snum));
@@ -3416,18 +3542,18 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
        }
 
        /* check the required size. */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding port [%d]'s size\n", i));
                *needed += spoolss_size_port_info_2(&(ports[i]));
        }
                
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(ports);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the ports structures */
-       for (i=0; i<*returned; i++)
-       {
+       for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding port [%d] to buffer\n", i));
                new_smb_io_port_2("", buffer, &(ports[i]), 0);
        }
@@ -3469,7 +3595,7 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
+static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
                                const SPOOL_PRINTER_INFO_LEVEL *info,
                                uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
                                uint32 user_switch, const  SPOOL_USER_CTR *user,
@@ -3481,45 +3607,63 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
 
        clear_handle(handle);
        
-/* 
- * FIX: JFM: we need to check the user here !!!!
- *
- * as the code is running as root, anybody can add printers to the server
- */
        /* NULLify info_2 here */
        /* don't put it in convert_printer_info as it's used also with non-NULL values */
        printer.info_2=NULL;
 
        /* convert from UNICODE to ASCII */
-       convert_printer_info(info, &printer, level);
+       convert_printer_info(info, &printer, 2);
 
-       unistr2_to_ascii(share_name, &((info->info_2)->portname), sizeof(share_name)-1);
+       unistr2_to_ascii(share_name, &((info->info_2)->printername), sizeof(share_name)-1);
        
        slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
 
+       /* write the ASCII on disk */
+       if (add_a_printer(printer, 2) != 0x0)
+               return ERROR_ACCESS_DENIED;
+
        create_printer_hnd(handle);
 
        open_printer_hnd(handle);
 
        if (!set_printer_hnd_printertype(handle, name)) {
                close_printer_handle(handle);
-               return NT_STATUS_ACCESS_DENIED;
+               return ERROR_ACCESS_DENIED;
        }
        
        if (!set_printer_hnd_printername(handle, name)) {
                close_printer_handle(handle);
-               return NT_STATUS_ACCESS_DENIED;
+               return ERROR_ACCESS_DENIED;
        }
 
-       /* write the ASCII on disk */
-       if (add_a_printer(printer, level) != 0x0) {
-               close_printer_handle(handle);
-               return NT_STATUS_ACCESS_DENIED;
+       return NT_STATUS_NO_PROBLEMO;
        }
        
-       return NT_STATUS_NO_PROBLEMO;
+/****************************************************************************
+****************************************************************************/
+uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
+                               const SPOOL_PRINTER_INFO_LEVEL *info,
+                               uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
+                               uint32 user_switch, const SPOOL_USER_CTR *user,
+                               POLICY_HND *handle)
+{
+       switch (level) {
+               case 1:
+                       /* we don't handle yet */
+                       /* but I know what to do ... */
+                       break;
+               case 2:
+                       return spoolss_addprinterex_level_2(uni_srv_name, info, 
+                                                           unk0, unk1, unk2, unk3,
+                                                           user_switch, user, handle);
+                       break;
+               default:
+                       return ERROR_INVALID_LEVEL;
+                       break;
+}
 }
 
+
 /****************************************************************************
 ****************************************************************************/
 uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
@@ -3565,8 +3709,10 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
        
        *needed += spoolss_size_driverdir_info_1(info);                                                     
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(info);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        new_smb_io_driverdir_1("", buffer, info, 0);
 
@@ -3593,7 +3739,7 @@ uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environmen
                return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
                break;
        default:
-               return NT_STATUS_INVALID_INFO_CLASS;
+               return ERROR_INVALID_LEVEL;
                break;
        }
 }
@@ -3604,7 +3750,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
                                uint32 in_value_len, uint32 in_data_len,
                                uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
                                uint32 *out_type,
-                               uint32 *out_max_data_len, uint8  **out_pdata, uint32 *out_data_len)
+                               uint32 *out_max_data_len, uint8  **data_out, uint32 *out_data_len)
 {
        NT_PRINTER_INFO_LEVEL printer;
        
@@ -3628,7 +3774,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
        *out_type=0;
 
        *out_max_data_len=0;
-       *out_pdata=NULL;
+       *data_out=NULL;
        *out_data_len=0;
 
        DEBUG(5,("spoolss_enumprinterdata\n"));
@@ -3681,7 +3827,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
  
        if (!get_specific_param_by_index(printer, 2, idx, value, &data, &type, &data_len)) {
                free_a_printer(printer, 2);
-               return 0x0103; /* ERROR_NO_MORE_ITEMS */
+               return ERROR_NO_MORE_ITEMS;
        }
                        
        /* 
@@ -3702,8 +3848,8 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
 
        /* the data is counted in bytes */
        *out_max_data_len=in_data_len;
-       *out_pdata=(uint8 *)malloc(in_data_len*sizeof(uint8));
-       memcpy(*out_pdata, data, data_len);
+       *data_out=(uint8 *)malloc(in_data_len*sizeof(uint8));
+       memcpy(*data_out, data, data_len);
        *out_data_len=data_len;
 
        safe_free(data);
@@ -4051,6 +4197,8 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
 
 /****************************************************************************
 ****************************************************************************/
+#if 0
+... Not yet used...
 static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        int i=0;
@@ -4090,6 +4238,7 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
        else
                return NT_STATUS_NO_PROBLEMO;
 }
+#endif
 
 /****************************************************************************
 ****************************************************************************/