more rewrite ...
authorJean-François Micouleau <jfm@samba.org>
Mon, 21 Feb 2000 01:58:13 +0000 (01:58 +0000)
committerJean-François Micouleau <jfm@samba.org>
Mon, 21 Feb 2000 01:58:13 +0000 (01:58 +0000)
comitting before starting on new functions.

J.F.

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

index b7a08e60de931b00ec34c9680be2dfe5c1b6cfb7..ee0de29eb63a2656177a8c7b6a8e8ce8aa0e4d6d 100644 (file)
@@ -2336,6 +2336,7 @@ BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u,
 BOOL spoolss_io_r_rfnpcnex(char *desc, 
                            SPOOL_R_RFNPCNEX *r_u, 
                            prs_struct *ps, int depth);
+BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth);
 BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth);
 BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth);
 BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ;
@@ -2348,11 +2349,13 @@ void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest);
 void new_spoolss_allocate_buffer(NEW_BUFFER **buffer);
 void new_spoolss_free_buffer(NEW_BUFFER *buffer);
 uint32 new_get_buffer_size(NEW_BUFFER *buffer);
+BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth);
 BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth);
 BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth);
 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth);
 BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth);
 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth);
+uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info);
 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info);
 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info);
 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info);
@@ -2362,33 +2365,26 @@ uint32 spoolss_size_job_info_1(JOB_INFO_1 *info);
 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info);
 uint32 spoolss_size_form_1(FORM_1 *info);
 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info);
+uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info);
 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info);
 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info);
 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
-BOOL spoolss_io_free_buffer(BUFFER *buffer);
-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 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,
                                const char* servername,
                                uint32 level,
                                uint32 size);
-BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u,
-                               prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth);
 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_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth);
 BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u,
                                POLICY_HND *hnd,
                                uint32 level,
                                uint32 buf_size);
-BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u,
-                               prs_struct *ps, int depth);
+BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth);
 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);
@@ -2427,8 +2423,8 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc);
 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
                               NT_PRINTER_INFO_LEVEL_2  **asc);
-BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
@@ -2444,7 +2440,6 @@ BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int
 BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
-void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u);
 BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
 void free_devmode(DEVICEMODE *devmode);
 void free_printer_info_2(PRINTER_INFO_2 *printer);
@@ -2639,17 +2634,11 @@ uint32 _spoolss_rfnpcnex( const POLICY_HND *handle,
 uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
                              NEW_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned);
-uint32 _spoolss_getprinter( POLICY_HND *handle,
-                               uint32 level,
-                               PRINTER_INFO *ctr,
-                               uint32 *offered,
-                               uint32 *needed);
-uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle,
-                               const UNISTR2 *uni_arch,
-                               uint32 level,
-                               DRIVER_INFO *ctr,
-                               uint32 *offered,
-                               uint32 *needed);
+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,
+                               NEW_BUFFER *buffer, uint32 offered,
+                               uint32 *needed, uint32 *unknown0, uint32 *unknown1);
 uint32 _spoolss_startpageprinter(const POLICY_HND *handle);
 uint32 _spoolss_endpageprinter(const POLICY_HND *handle);
 uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
@@ -2668,8 +2657,7 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle,
                                uint32 command);
 uint32 _spoolss_fcpn( const POLICY_HND *handle);
 uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level,
-                               const BUFFER *buffer,
-                               uint32 buf_size);
+                       NEW_BUFFER *buffer, uint32 offered);
 uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,                   
                          NEW_BUFFER *buffer, uint32 offered,
                          uint32 *needed, uint32 *returned);
@@ -2688,24 +2676,17 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level,
 uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, 
                           NEW_BUFFER *buffer, uint32 offered, 
                           uint32 *needed, uint32 *returned);
-uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_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_level,
-                               const SPOOL_USER_LEVEL *user,
+                               uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
+                               uint32 user_switch, const  SPOOL_USER_CTR *user,
                                POLICY_HND *handle);
 uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
                                uint32 level,
                                const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info);
-uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name,
-                               const UNISTR2 *uni_environment,
-                               uint32 level,
-                               DRIVER_DIRECTORY_CTR *ctr,
-                               uint32 *offered);
+uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
+                                       NEW_BUFFER *buffer, uint32 offered, 
+                                       uint32 *needed);
 uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, 
                                uint32 idx,
                                uint32 *valuesize,
@@ -2735,11 +2716,9 @@ uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32
 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
                                    NEW_BUFFER *buffer, uint32 offered, 
                                    uint32 *needed, uint32 *returned);
-uint32 _spoolss_getjob( const POLICY_HND *handle,
-                               uint32 jobid,
-                               uint32 level,
-                               PJOB_INFO *ctr,
-                               uint32 *offered);
+uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
+                       NEW_BUFFER *buffer, uint32 offered, 
+                       uint32 *needed);
 
 /*The following definitions come from  rpc_server/srv_srvsvc.c  */
 
index fc8fd041d682b63f0afea25d24a550a95627329c..1556c56686bf669005709a046979bfd4ccedf713 100755 (executable)
@@ -381,7 +381,7 @@ typedef struct spool_q_open_printer_ex
        SPOOL_USER_CTR user_ctr;
 } SPOOL_Q_OPEN_PRINTER_EX;
 
-/* SPOOL_Q_OPEN_PRINTER_EX reply to an open printer */ 
+/* SPOOL_R_OPEN_PRINTER_EX reply to an open printer */ 
 typedef struct spool_r_open_printer_ex
 {      
        POLICY_HND handle; /* handle used along all transactions (20*uint8) */
@@ -410,7 +410,7 @@ typedef struct s_header_type
        } data;
 } HEADER_TYPE;
 
-typedef struct s_buffer
+/*typedef struct s_buffer
 {
        uint32 ptr;
        uint32 size;
@@ -418,7 +418,7 @@ typedef struct s_buffer
        uint8 *data;
        HEADER_TYPE *header;
 } BUFFER;
-
+*/
 typedef struct new_buffer
 {
        uint32 ptr;
@@ -716,9 +716,8 @@ typedef struct spool_q_getprinter
 {
        POLICY_HND handle;
        uint32 level;
-       uint8* buffer;
+       NEW_BUFFER *buffer;
        uint32 offered;
-
 } SPOOL_Q_GETPRINTER;
 
 typedef struct printer_info_info
@@ -729,17 +728,11 @@ typedef struct printer_info_info
                PRINTER_INFO_2 *info2;
                void *info;
        } printer;
-
 } PRINTER_INFO;
 
 typedef struct spool_r_getprinter
 {
-       POLICY_HND handle;
-       uint32 level;
-
-       PRINTER_INFO ctr;
-
-       uint32 offered;
+       NEW_BUFFER *buffer;
        uint32 needed;
        uint32 status;
 
@@ -754,17 +747,6 @@ struct s_notify_info_data_table
        void   (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer);
 };
 
-typedef struct spool_q_getprinterdriver2
-{
-       POLICY_HND handle;
-       UNISTR2 architecture;
-       uint32 level;
-       BUFFER buffer;
-       uint32 buf_size;
-       uint32 unknown;
-
-} SPOOL_Q_GETPRINTERDRIVER2;
-
 typedef struct driver_info_1
 {
        UNISTR name;
@@ -804,17 +786,27 @@ typedef struct driver_info_info
 
 } DRIVER_INFO;
 
-typedef struct spool_r_getprinterdriver2
+typedef struct spool_q_getprinterdriver2
 {
+       POLICY_HND handle;
+       uint32 architecture_ptr;
+       UNISTR2 architecture;
        uint32 level;
-       DRIVER_INFO ctr;
-       uint32 needed;
+       NEW_BUFFER *buffer;
        uint32 offered;
-       uint32 returned;
-       uint32 status;
+       uint32 unknown;
+} SPOOL_Q_GETPRINTERDRIVER2;
 
+typedef struct spool_r_getprinterdriver2
+{
+       NEW_BUFFER *buffer;
+       uint32 needed;
+       uint32 unknown0;
+       uint32 unknown1;
+       uint32 status;
 } SPOOL_R_GETPRINTERDRIVER2;
 
+
 typedef struct add_jobinfo_1
 {
        UNISTR path;
@@ -826,8 +818,8 @@ typedef struct spool_q_addjob
 {
        POLICY_HND handle;
        uint32 level;
-       BUFFER buffer;
-       uint32 buf_size;
+       NEW_BUFFER *buffer;
+       uint32 offered;
 } SPOOL_Q_ADDJOB;
 
 typedef struct spool_r_addjob
@@ -1125,6 +1117,8 @@ typedef struct spool_printer_driver_info_level_3
 
 typedef struct spool_printer_driver_info_level
 {
+       uint32 level;
+       uint32 ptr;
        SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3;
 } SPOOL_PRINTER_DRIVER_INFO_LEVEL;
 
@@ -1191,8 +1185,10 @@ typedef struct spool_r_addprinter
        uint32 status;
 } SPOOL_R_ADDPRINTER;
 
+
 typedef struct spool_q_addprinterex
 {
+       uint32 server_name_ptr;
        UNISTR2 server_name;
        uint32 level;
        SPOOL_PRINTER_INFO_LEVEL info;
@@ -1200,19 +1196,20 @@ typedef struct spool_q_addprinterex
        uint32 unk1;
        uint32 unk2;
        uint32 unk3;
-       uint32 user_level;
-       SPOOL_USER_LEVEL user;
+       uint32 user_switch;
+       SPOOL_USER_CTR user_ctr;
 } SPOOL_Q_ADDPRINTEREX;
 
-
 typedef struct spool_r_addprinterex
 {
        POLICY_HND handle;
        uint32 status;
 } SPOOL_R_ADDPRINTEREX;
 
+
 typedef struct spool_q_addprinterdriver
 {
+       uint32 server_name_ptr;
        UNISTR2 server_name;
        uint32 level;
        SPOOL_PRINTER_DRIVER_INFO_LEVEL info;
@@ -1223,19 +1220,10 @@ typedef struct spool_r_addprinterdriver
        uint32 status;
 } SPOOL_R_ADDPRINTERDRIVER;
 
-typedef struct spool_q_getprinterdriverdirectory
-{
-       UNISTR2 name;
-       UNISTR2 environment;
-       uint32 level;
-       BUFFER buffer;
-       uint32 buf_size;
-} SPOOL_Q_GETPRINTERDRIVERDIR;
 
 typedef struct driver_directory_1
 {
        UNISTR name;
-
 } DRIVER_DIRECTORY_1 ;
 
 typedef struct driver_info_ctr_info
@@ -1243,16 +1231,24 @@ typedef struct driver_info_ctr_info
        union {
                DRIVER_DIRECTORY_1 info_1;
        } driver;
-
 } DRIVER_DIRECTORY_CTR;
 
-typedef struct spool_r_getprinterdriverdirectory
+typedef struct spool_q_getprinterdriverdirectory
 {
+       uint32 name_ptr;
+       UNISTR2 name;
+       uint32 environment_ptr;
+       UNISTR2 environment;
        uint32 level;
-       DRIVER_DIRECTORY_CTR ctr;
+       NEW_BUFFER *buffer;
        uint32 offered;
-       uint32 status;
+} SPOOL_Q_GETPRINTERDRIVERDIR;
 
+typedef struct spool_r_getprinterdriverdirectory
+{
+       NEW_BUFFER *buffer;
+       uint32 needed;
+       uint32 status;
 } SPOOL_R_GETPRINTERDRIVERDIR;
 
 typedef struct spool_q_enumprintprocessors
@@ -1284,7 +1280,7 @@ typedef struct spool_q_enumprintprocessordatatypes
        UNISTR2 name;
        UNISTR2 printprocessor;
        uint32 level;
-       BUFFER buffer;
+       NEW_BUFFER *buffer;
        uint32 buf_size;
 } SPOOL_Q_ENUMPRINTPROCESSORDATATYPES;
 
@@ -1413,9 +1409,8 @@ typedef struct spool_q_getjob
        POLICY_HND handle;
        uint32 jobid;
        uint32 level;
-       BUFFER buffer;
-       uint32 buf_size;
-
+       NEW_BUFFER *buffer;
+       uint32 offered;
 } SPOOL_Q_GETJOB;
 
 typedef struct pjob_info_info
@@ -1430,9 +1425,8 @@ typedef struct pjob_info_info
 
 typedef struct spool_r_getjob
 {
-       uint32 level;
-       PJOB_INFO ctr;
-       uint32 offered;
+       NEW_BUFFER *buffer;
+       uint32 needed;
        uint32 status;
 } SPOOL_R_GETJOB;
 
index 66fa2f1da5aa4729abc2cadb27c484d32d74b6bf..796466337f8a4cdd6cacdca191597d6e100d54a2 100644 (file)
@@ -675,21 +675,20 @@ BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("printername_ptr", ps, depth, &(q_u->printername_ptr)))
+       if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
                return False;
-       if (!smb_io_unistr2("", &(q_u->printername), q_u->printername_ptr, ps,depth))
+       if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
                return False;
        
        if (!prs_align(ps))
                return False;
 
-       if (!spoolss_io_printer_default("", &(q_u->printer_default), ps, depth))
+       if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
                return False;
                
-       if (!prs_uint32("user_switch", ps, depth, &(q_u->user_switch)))
-               return False;
-       
-       if (!spool_io_user_level("", &(q_u->user_ctr), ps, depth))
+       if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
+               return False;   
+       if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
                return False;
                
        return True;
@@ -1116,8 +1115,6 @@ BOOL spoolss_io_r_rfnpcnex(char *desc,
 static uint32 size_of_uint32(uint32 *value)
 {
        return (sizeof(*value));
-
-       return True;
 }
 
 /*******************************************************************
@@ -1133,9 +1130,8 @@ static uint32 size_of_relative_string(UNISTR *string)
        size=size+1;                    /* add the leading zero    */
        size=size*2;                    /* convert in char         */
        size=size+4;                    /* add the size of the ptr */   
-       return (size);
 
-       return True;
+       return size;
 }
 
 /*******************************************************************
@@ -1147,8 +1143,6 @@ static uint32 size_of_device_mode(DEVICEMODE *devmode)
                return (4);
        else 
                return (0xDC+4);
-
-       return True;
 }
 
 /*******************************************************************
@@ -1160,8 +1154,6 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime)
                return (4);
        else 
                return (sizeof(SYSTEMTIME) +4);
-
-       return True;
 }
 
 /*******************************************************************
@@ -1177,8 +1169,6 @@ static BOOL spoolss_smb_io_unistr(char *desc,  UNISTR *uni, prs_struct *ps, int
        depth++;
        if (!prs_unistr("unistr", ps, depth, uni))
                return False;
-
-       return True;
 }
 
 
@@ -1457,45 +1447,79 @@ static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE
 }
 
 /*******************************************************************
+ Parse a PRINTER_INFO_0 structure.
 ********************************************************************/  
-static BOOL smb_io_printer_info_0(char *desc, PRINTER_INFO_0 *info, prs_struct *ps, int depth, 
-                                  uint32 *start_offset, uint32 *end_offset)
+BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
 {
+       prs_struct *ps=&(buffer->prs);
+
        prs_debug(ps, depth, desc, "smb_io_printer_info_0");
        depth++;        
-       *start_offset=prs_offset(ps);
        
-       smb_io_relstr("printername",ps, depth, &(info->printername), start_offset, end_offset);
-       smb_io_relstr("servername",ps, depth, &(info->servername), start_offset, end_offset);
-       prs_uint32("cjobs", ps, depth, &(info->cjobs));
-       prs_uint32("attributes", ps, depth, &(info->attributes));
-
-       prs_uint32("unknown0", ps, depth, &(info->unknown0));
-       prs_uint32("unknown1", ps, depth, &(info->unknown1));
-       prs_uint32("unknown2", ps, depth, &(info->unknown2));
-       prs_uint32("unknown3", ps, depth, &(info->unknown3));
-       prs_uint32("unknown4", ps, depth, &(info->unknown4));
-       prs_uint32("unknown5", ps, depth, &(info->unknown5));
-       prs_uint32("unknown6", ps, depth, &(info->unknown6));
-       prs_uint16("majorversion", ps, depth, &(info->majorversion));
-       prs_uint16("buildversion", ps, depth, &(info->buildversion));
-       prs_uint32("unknown7", ps, depth, &(info->unknown7));
-       prs_uint32("unknown8", ps, depth, &(info->unknown8));
-       prs_uint32("unknown9", ps, depth, &(info->unknown9));
-       prs_uint32("unknown10", ps, depth, &(info->unknown10));
-       prs_uint32("unknown11", ps, depth, &(info->unknown11));
-       prs_uint32("unknown12", ps, depth, &(info->unknown12));
-       prs_uint32("unknown13", ps, depth, &(info->unknown13));
-       prs_uint32("unknown14", ps, depth, &(info->unknown14));
-       prs_uint32("unknown15", ps, depth, &(info->unknown15));
-       prs_uint32("unknown16", ps, depth, &(info->unknown16));
-       prs_uint32("unknown17", ps, depth, &(info->unknown17));
-       prs_uint32("unknown18", ps, depth, &(info->unknown18));
-       prs_uint32("status"   , ps, depth, &(info->status));
-       prs_uint32("unknown20", ps, depth, &(info->unknown20));
-       prs_uint32("unknown21", ps, depth, &(info->unknown21));
-       prs_uint16("unknown22", ps, depth, &(info->unknown22));
-       prs_uint32("unknown23", ps, depth, &(info->unknown23));
+       buffer->struct_start=prs_offset(ps);
+
+       if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
+               return False;
+       if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
+               return False;
+       
+       if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
+               return False;
+       if(!prs_uint32("attributes", ps, depth, &info->attributes))
+               return False;
+
+       if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
+               return False;
+       if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
+               return False;
+       if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
+               return False;
+       if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
+               return False;
+       if(!prs_uint32("unknown4", ps, depth, &info->unknown4))
+               return False;
+       if(!prs_uint32("unknown5", ps, depth, &info->unknown5))
+               return False;
+       if(!prs_uint32("unknown6", ps, depth, &info->unknown6))
+               return False;
+       if(!prs_uint16("majorversion", ps, depth, &info->majorversion))
+               return False;
+       if(!prs_uint16("buildversion", ps, depth, &info->buildversion))
+               return False;
+       if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
+               return False;
+       if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
+               return False;
+       if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
+               return False;
+       if(!prs_uint32("unknown10", ps, depth, &info->unknown10))
+               return False;
+       if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
+               return False;
+       if(!prs_uint32("unknown12", ps, depth, &info->unknown12))
+               return False;
+       if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
+               return False;
+       if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
+               return False;
+       if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
+               return False;
+       if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
+               return False;
+       if(!prs_uint32("unknown17", ps, depth, &info->unknown17))
+               return False;
+       if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
+               return False;
+       if(!prs_uint32("status"   , ps, depth, &info->status))
+               return False;
+       if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
+               return False;
+       if(!prs_uint32("unknown21", ps, depth, &info->unknown21))
+               return False;
+       if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
+               return False;
+       if(!prs_uint32("unknown23", ps, depth, &info->unknown23))
+               return False;
 
        return True;
 }
@@ -1767,30 +1791,6 @@ BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int
        return True;
 }
 
-static BOOL smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int depth, 
-                              uint32 *start_offset, uint32 *end_offset)
-{
-       prs_debug(ps, depth, desc, "smb_io_job_info_1");
-       depth++;        
-       *start_offset=prs_offset(ps);
-       
-       prs_uint32("jobid",                 ps, depth, &(info->jobid));
-       smb_io_relstr("printername",        ps, depth, &(info->printername), start_offset, end_offset);
-       smb_io_relstr("machinename",        ps, depth, &(info->machinename), start_offset, end_offset);
-       smb_io_relstr("username",           ps, depth, &(info->username), start_offset, end_offset);
-       smb_io_relstr("document",           ps, depth, &(info->document), start_offset, end_offset);
-       smb_io_relstr("datatype",           ps, depth, &(info->datatype), start_offset, end_offset);
-       smb_io_relstr("text_status",        ps, depth, &(info->text_status), start_offset, end_offset);
-       prs_uint32("status",                ps, depth, &(info->status));
-       prs_uint32("priority",              ps, depth, &(info->priority));
-       prs_uint32("position",              ps, depth, &(info->position));
-       prs_uint32("totalpages",            ps, depth, &(info->totalpages));
-       prs_uint32("pagesprinted",          ps, depth, &(info->pagesprinted));
-       spoolss_io_system_time("submitted", ps, depth, &(info->submitted) );
-
-       return True;
-}
-
 /*******************************************************************
  Parse a JOB_INFO_2 structure.
 ********************************************************************/  
@@ -1857,44 +1857,6 @@ BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int
 
        return True;
 }
-static BOOL smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth, 
-                              uint32 *start_offset, uint32 *end_offset)
-{      
-       int pipo=0;
-       prs_debug(ps, depth, desc, "smb_io_job_info_2");
-       depth++;        
-       *start_offset=prs_offset(ps);
-       
-       prs_uint32("jobid",                 ps, depth, &(info->jobid));
-       smb_io_relstr("printername",        ps, depth, &(info->printername), start_offset, end_offset);
-       smb_io_relstr("machinename",        ps, depth, &(info->machinename), start_offset, end_offset);
-       smb_io_relstr("username",           ps, depth, &(info->username), start_offset, end_offset);
-       smb_io_relstr("document",           ps, depth, &(info->document), start_offset, end_offset);
-       smb_io_relstr("notifyname",         ps, depth, &(info->notifyname), start_offset, end_offset);
-       smb_io_relstr("datatype",           ps, depth, &(info->datatype), start_offset, end_offset);
-
-       smb_io_relstr("printprocessor",     ps, depth, &(info->printprocessor), start_offset, end_offset);
-       smb_io_relstr("parameters",         ps, depth, &(info->parameters), start_offset, end_offset);
-       smb_io_relstr("drivername",         ps, depth, &(info->drivername), start_offset, end_offset);
-       smb_io_reldevmode("devmode",        ps, depth, info->devmode, start_offset, end_offset);
-       smb_io_relstr("text_status",        ps, depth, &(info->text_status), start_offset, end_offset);
-
-/*     SEC_DESC sec_desc;*/
-       prs_uint32("Hack! sec desc", ps, depth, &pipo);
-
-       prs_uint32("status",                ps, depth, &(info->status));
-       prs_uint32("priority",              ps, depth, &(info->priority));
-       prs_uint32("position",              ps, depth, &(info->position));      
-       prs_uint32("starttime",             ps, depth, &(info->starttime));
-       prs_uint32("untiltime",             ps, depth, &(info->untiltime));     
-       prs_uint32("totalpages",            ps, depth, &(info->totalpages));
-       prs_uint32("size",                  ps, depth, &(info->size));
-       spoolss_io_system_time("submitted", ps, depth, &(info->submitted) );
-       prs_uint32("timeelapsed",           ps, depth, &(info->timeelapsed));
-       prs_uint32("pagesprinted",          ps, depth, &(info->pagesprinted));
-
-       return True;
-}
 
 /*******************************************************************
 ********************************************************************/  
@@ -2056,8 +2018,27 @@ static BOOL smb_io_form_1(char *desc, FORM_1 *info, prs_struct *ps, int depth,
 
        return True;
 }
+
 /*******************************************************************
- Parse a PORT_INFO_2 structure.
+ Parse a DRIVER_DIRECTORY_1 structure.
+********************************************************************/  
+BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
+{
+       prs_struct *ps=&(buffer->prs);
+
+       prs_debug(ps, depth, desc, "new_smb_io_driverdir_1");
+       depth++;
+
+       buffer->struct_start=prs_offset(ps);
+
+       if(!new_smb_io_relstr("name", buffer, depth, &info->name))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Parse a PORT_INFO_1 structure.
 ********************************************************************/  
 BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
 {
@@ -2174,16 +2155,18 @@ BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *
 /*******************************************************************
 return the size required by a struct in the stream
 ********************************************************************/  
-static uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
+uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
 {
        int size=0;
-               
+       
+       size+=24*4;
+       size+=6;
+       
        size+=size_of_uint32( &(info->attributes) );    
        size+=size_of_relative_string( &(info->printername) );
        size+=size_of_relative_string( &(info->servername) );
-       return (size);
 
-       return True;
+       return size;
 }
 
 /*******************************************************************
@@ -2242,13 +2225,9 @@ return the size required by a struct in the stream
 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
 {
        int size=0;
-       DEBUG(9,("Sizing driver info_1\n"));
        size+=size_of_relative_string( &(info->name) );
 
-       DEBUGADD(9,("size: [%d]\n", size));
-       return (size);
-
-       return True;
+       return size;
 }
 
 /*******************************************************************
@@ -2257,7 +2236,6 @@ return the size required by a struct in the stream
 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
 {
        int size=0;
-       DEBUG(9,("Sizing driver info_2\n"));
        size+=size_of_uint32( &(info->version) );       
        size+=size_of_relative_string( &(info->name) );
        size+=size_of_relative_string( &(info->architecture) );
@@ -2265,10 +2243,7 @@ uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
        size+=size_of_relative_string( &(info->datafile) );
        size+=size_of_relative_string( &(info->configfile) );
 
-       DEBUGADD(9,("size: [%d]\n", size));
-       return (size);
-
-       return True;
+       return size;
 }
 
 /*******************************************************************
@@ -2280,7 +2255,6 @@ uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
        UNISTR **string;
        int i=0;
 
-       DEBUG(9,("Sizing driver info_3\n"));
        size+=size_of_uint32( &(info->version) );       
        size+=size_of_relative_string( &(info->name) );
        size+=size_of_relative_string( &(info->architecture) );
@@ -2300,10 +2274,7 @@ uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
        }
        size+=6;
 
-       DEBUGADD(9,("size: [%d]\n", size));
-       return (size);
-
-       return True;
+       return size;
 }
 
 /*******************************************************************
@@ -2361,9 +2332,8 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
        size+=size_of_systemtime( &(info->submitted) );
        size+=size_of_uint32( &(info->timeelapsed) );
        size+=size_of_uint32( &(info->pagesprinted) );
-       return (size);
 
-       return True;
+       return size;
 }
 
 /*******************************************************************
@@ -2392,7 +2362,19 @@ uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
 {
        int size=0;
 
-       size+=size_of_relative_string( &(info->port_name) );
+       size+=size_of_relative_string( &info->port_name );
+
+       return size;
+}
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/  
+uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
+{
+       int size=0;
+
+       size+=size_of_relative_string( &info->name );
 
        return size;
 }
@@ -2404,12 +2386,12 @@ uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
 {
        int size=0;
 
-       size+=size_of_relative_string( &(info->port_name) );
-       size+=size_of_relative_string( &(info->monitor_name) );
-       size+=size_of_relative_string( &(info->description) );
+       size+=size_of_relative_string( &info->port_name );
+       size+=size_of_relative_string( &info->monitor_name );
+       size+=size_of_relative_string( &info->description );
 
-       size+=size_of_uint32( &(info->port_type) );
-       size+=size_of_uint32( &(info->reserved) );
+       size+=size_of_uint32( &info->port_type );
+       size+=size_of_uint32( &info->reserved );
 
        return size;
 }
@@ -2434,7 +2416,6 @@ uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
        size+=size_of_relative_string( &info->name );
 
        return size;
-
 }
 
 /*******************************************************************
@@ -2450,123 +2431,41 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
        return size;
 }
 
-/*******************************************************************
- * make a structure.
- ********************************************************************/
-/*
-static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size)
-{
-       buffer->ptr = (size != 0) ? 1 : 0;
-       buffer->size = size;
-       buffer->data = (uint8 *)Realloc( NULL, (buffer->size) * sizeof(uint8) );
-
-       return (buffer->data != NULL || size == 0);
-}
-*/
-
-/*******************************************************************
- * read a uint8 buffer of size *size.
- * allocate memory for it
- * return a pointer to the allocated memory and the size
- * return NULL and a size of 0 if the buffer is empty
- *
- * jfmxxxx: fix it to also write a buffer
- ********************************************************************/
-static BOOL spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER *buffer)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_read_buffer");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("pointer", ps, depth, &(buffer->ptr));
-       
-       if (buffer->ptr != 0x0000)
-       {
-               prs_uint32("size", ps, depth, &(buffer->size)); 
-               if (ps->io)
-               {
-                       /* reading */
-                       buffer->data=(uint8 *)Realloc(NULL, buffer->size * sizeof(uint8) );
-               }
-               if (buffer->data == NULL)
-               {
-                       return False;
-               }
-               prs_uint8s(True, "buffer", ps, depth, buffer->data, buffer->size);      
-               prs_align(ps);
-
-       }
-       else
-       {
-               if (ps->io)
-               {
-                       /* reading */
-                       buffer->data=0x0000;
-                       buffer->size=0x0000;
-               }
-       }
-
-       if (!ps->io)
-       {
-               /* writing */
-               if (buffer->data != NULL)
-               {
-                       free(buffer->data);
-               }
-               buffer->data = NULL;
-       }
-       return True;
-}
-
-/*******************************************************************
- * read a uint8 buffer of size *size.
- * allocate memory for it
- * return a pointer to the allocated memory and the size
- * return NULL and a size of 0 if the buffer is empty
- *
- * jfmxxxx: fix it to also write a buffer
- ********************************************************************/
-BOOL spoolss_io_free_buffer(BUFFER *buffer)
-{
-       DEBUG(8,("spoolss_io_free_buffer\n"));
-
-       if (buffer->ptr != 0x0000)
-       {
-              free(buffer->data);
-       }
-
-       return True;
-}
-
 /*******************************************************************
  * read a structure.
  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
  ********************************************************************/
-BOOL spoolss_io_q_getprinterdriver2(char *desc, 
-                                   SPOOL_Q_GETPRINTERDRIVER2 *q_u,
-                                    prs_struct *ps, int depth)
+BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
 {
-       uint32 useless_ptr;
        prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
        depth++;
 
-       prs_align(ps);
-       
-       smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-       smb_io_unistr2("architecture", &(q_u->architecture),True,ps,depth);
+       if(!prs_align(ps))
+               return False;
        
-       prs_align(ps);
+       if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
+               return False;
+       if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
+               return False;
+       if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
+               return False;
        
-       prs_uint32("level", ps, depth, &(q_u->level));
-       spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+       if(!prs_align(ps))
+               return False;
+               if(!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
+               
+       if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("buffer size", ps, depth, &(q_u->buf_size));
-       DEBUG(0,("spoolss_io_q_getprinterdriver2: renamed status - unknown\n"));
-       prs_uint32("unknown", ps, depth, &(q_u->unknown));
+       if(!prs_uint32("offered", ps, depth, &q_u->offered))
+               return False;
+               
+       if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
+               return False;
 
        return True;
 }
@@ -2575,164 +2474,44 @@ BOOL spoolss_io_q_getprinterdriver2(char *desc,
  * read a structure.
  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
  ********************************************************************/
-BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
-                               prs_struct *ps, int depth)
+BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
 {
-       uint32 useless_ptr=0xADDE0FF0;
-       uint32 start_offset, end_offset, beginning;
-       uint32 bufsize_required=0;
-       uint32 pipo=0;
-       DRIVER_INFO_1 *info1;
-       DRIVER_INFO_2 *info2;
-       DRIVER_INFO_3 *info3;
-
        prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
        depth++;
 
-       prs_align(ps);  
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-       
-       info1 = r_u->ctr.driver.info1;
-       info2 = r_u->ctr.driver.info2;
-       info3 = r_u->ctr.driver.info3;
-
-       switch (r_u->level)
-       {
-               case 1:
-               {
-                       bufsize_required += spoolss_size_printer_driver_info_1(info1);  
-                       break;
-               }
-               case 2:
-               {
-                       bufsize_required += spoolss_size_printer_driver_info_2(info2);  
-                       break;
-               }
-               case 3:
-               {
-                       bufsize_required += spoolss_size_printer_driver_info_3(info3);  
-                       break;
-               }       
-       }
-
-       if (ps->io)
-       {
-               /* reading */
-               r_u->offered = bufsize_required;
-       }
-
-       DEBUG(4,("spoolss_io_r_getprinterdriver2, size needed: %d\n",bufsize_required));
-       DEBUG(4,("spoolss_io_r_getprinterdriver2, size offered: %d\n",r_u->offered));
-
-       /* check if the buffer is big enough for the datas */
-       if (r_u->offered < bufsize_required)
-       {       
-               /* it's too small */
-               r_u->status=ERROR_INSUFFICIENT_BUFFER;  /* say so */
-               r_u->offered=0;                         /* don't send back the buffer */
+       if (!prs_align(ps))
+               return False;
                
-               DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer too small\n"));
+       if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
+               return False;
 
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-       }
-       else
-       {       
-               DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer large enough\n"));
-       
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+       if (!prs_align(ps))
+               return False;
+       if (!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
+       if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
+               return False;
+       if (!prs_uint32("unknown1", ps, depth, &r_u->unknown1))
+               return False;           
+       if (!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
-               beginning=prs_offset(ps);
-               start_offset=prs_offset(ps);
-               end_offset=start_offset+r_u->offered;
-               
-               switch (r_u->level)
-               {
-                       case 1:
-                       {
-                               smb_io_printer_driver_info_1(desc, 
-                                                            info1, 
-                                                            ps, 
-                                                            depth, 
-                                                            &start_offset, 
-                                                            &end_offset);
-                               break;
-                       }
-                       case 2:
-                       {
-                               smb_io_printer_driver_info_2(desc, 
-                                                            info2, 
-                                                            ps, 
-                                                            depth, 
-                                                            &start_offset, 
-                                                            &end_offset);
-                               break;
-                       }
-                       case 3:
-                       {
-                               smb_io_printer_driver_info_3(desc, 
-                                                            info3, 
-                                                            ps, 
-                                                            depth, 
-                                                            &start_offset, 
-                                                            &end_offset);
-                               break;
-                       }
-               
-               }       
-               
-               prs_set_offset(ps, beginning+r_u->offered);
-               prs_align(ps);  
-       }
-       
-       if (!ps->io)
+       return True;            
+}
+
+/*
+       UNISTR **dependentfiles;
+       int j=0;
+       dependentfiles=info3->dependentfiles;
+       while ( dependentfiles[j] != NULL )
        {
-               /* writing */
-               switch (r_u->level)
-               {
-                       case 1:
-                       {
-                               safe_free(info1);
-                               break;
-                       }
-                       case 2:
-                       {
-                               safe_free(info2);
-                               break;
-                       }
-                       case 3:
-                       {
-                               if (info3!=NULL) 
-                               {
-                                       UNISTR **dependentfiles;
-                                       int j=0;
-                                       dependentfiles=info3->dependentfiles;
-                                       while ( dependentfiles[j] != NULL )
-                                       {
-                                               free(dependentfiles[j]);
-                                               j++;
-                                       }
-                                       free(dependentfiles);
-                               
-                                       free(info3);
-                               }
-                               break;
-                       }
-               
-               }       
+               free(dependentfiles[j]);
+               j++;
        }
+       free(dependentfiles);
 
-       /*
-        * if the buffer was too small, send the minimum required size
-        * if it was too large, send the real needed size
-        */
-               
-       prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
-       prs_uint32("pipo", ps, depth, &pipo);
-       prs_uint32("pipo", ps, depth, &pipo);
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
+       free(info3);
+*/
 
 /*******************************************************************
  * make a structure.
@@ -2762,8 +2541,7 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u,
  * read a structure.
  * called from spoolss_enumprinters (srv_spoolss.c)
  ********************************************************************/
-BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u,
-                               prs_struct *ps, int depth)
+BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
 {
        prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
        depth++;
@@ -2829,175 +2607,27 @@ BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_st
  * called from spoolss_r_enum_printers (srv_spoolss.c)
  *
  ********************************************************************/
-BOOL spoolss_io_r_getprinter(char *desc,
-                               SPOOL_R_GETPRINTER *r_u, 
-                               prs_struct *ps, int depth)
+BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
 {      
-       uint32 useless_ptr=0xADDE0FF0;
-       uint32 start_offset, end_offset, beginning;
-       uint32 bufsize_required=0;
-       
        prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-
-       switch (r_u->level)
-       {
-               case 0:
-               {
-                       PRINTER_INFO_0 *info;
-                       info = r_u->ctr.printer.info0;
-                       bufsize_required += spoolss_size_printer_info_0(info);  
-                       break;
-               }
-               case 1:
-               {
-                       PRINTER_INFO_1 *info;
-                       info = r_u->ctr.printer.info1;
-                       bufsize_required += spoolss_size_printer_info_1(info);  
-                       break;
-               }
-               case 2:
-               {
-                       PRINTER_INFO_2 *info;
-                       info = r_u->ctr.printer.info2;
-                       bufsize_required += spoolss_size_printer_info_2(info);  
-                       break;
-               }       
-       }
-       
-       DEBUG(4,("spoolss_io_r_getprinter, size needed: %d\n",bufsize_required));
-       DEBUG(4,("spoolss_io_r_getprinter, size offered: %d\n",r_u->offered));
-
-       /* check if the buffer is big enough for the datas */
-       if (r_u->offered < bufsize_required)
-       {       
-               /* it's too small */
-               r_u->status = ERROR_INSUFFICIENT_BUFFER;        /* say so */
-               r_u->offered = 0;                               /* don't send back the buffer */
+       if (!prs_align(ps))
+               return False;
                
-               DEBUG(4,("spoolss_io_r_getprinter, buffer too small\n"));
-
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-       }
-       else
-       {       
-               DEBUG(4,("spoolss_io_r_getprinter, buffer large enough\n"));
-       
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-       }
-
-       if (ps->io)
-       {
-               /* reading */
-               r_u->ctr.printer.info = Realloc(NULL, r_u->offered);
-       }
+       if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
+               return False;
 
-       if (bufsize_required <= r_u->offered)
-       {
-               beginning=prs_offset(ps);
-               start_offset=prs_offset(ps);
-               end_offset=start_offset+r_u->offered;
-               
-               switch (r_u->level)
-               {
-                       case 0:
-                       {
-                               PRINTER_INFO_0 *info;
-                               info = r_u->ctr.printer.info0;
-                               smb_io_printer_info_0(desc, 
-                                                     info, 
-                                                     ps, 
-                                                     depth, 
-                                                     &start_offset, 
-                                                     &end_offset);
-                               if (!ps->io)
-                               {
-                                       /* writing */
-                                       free(info);
-                               }
-                               break;
-                       }
-                       case 1:
-                       {
-                               PRINTER_INFO_1 *info;
-                               info = r_u->ctr.printer.info1;
-                               /*
-                               smb_io_printer_info_1(desc, 
-                                                     info, 
-                                                     ps, 
-                                                     depth, 
-                                                     &start_offset, 
-                                                     &end_offset);
-                               */
-                               if (!ps->io)
-                               {
-                                       /* writing */
-                                       free(info);
-                               }
-                               break;
-                       }
-                       case 2:
-                       {
-                               PRINTER_INFO_2 *info;
-                               info = r_u->ctr.printer.info2;
-                               /*
-                               smb_io_printer_info_2(desc, 
-                                                     info, 
-                                                     ps, 
-                                                     depth, 
-                                                     &start_offset, 
-                                                     &end_offset);
-                               */
-                               if (!ps->io)
-                               {
-                                       /* writing */
-                                       free_printer_info_2(info);
-                               }
-                               break;
-                       }
+       if (!prs_align(ps))
+               return False;
                
-               }       
+       if (!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
                
-               prs_set_offset(ps, beginning+r_u->offered);
-               prs_align(ps);
-       }
-       
-       /*
-        * if the buffer was too small, send the minimum required size
-        * if it was too large, send the real needed size
-        */
-               
-       prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
- * read a uint8 buffer of size *size.
- * allocate memory for it
- * return a pointer to the allocated memory and the size
- * return NULL and a size of 0 if the buffer is empty
- *
- * jfmxxxx: fix it to also write a buffer
- ********************************************************************/
-static BOOL spoolss_io_read_buffer8(char *desc, prs_struct *ps, uint8 **buffer, uint32 *size,int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_read_buffer8");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("buffer size", ps, depth, size);     
-       *buffer = (uint8 *)Realloc(NULL, (*size) * sizeof(uint8) );
-       prs_uint8s(True,"buffer",ps,depth,*buffer,*size);       
-       prs_align(ps);
+       if (!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
-       return True;
+       return True;            
 }
 
 /*******************************************************************
@@ -3024,38 +2654,28 @@ BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u,
  * read a structure.
  * called from spoolss_getprinter (srv_spoolss.c)
  ********************************************************************/
-BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u,
-                               prs_struct *ps, int depth)
+BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
 {
-       uint32 count = 0;
-       uint32 buf_ptr = q_u->buffer != NULL ? 1 : 0;
        prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
        depth++;
 
-       prs_align(ps);
+       if (!prs_align(ps))
+               return False;
 
-       smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
-       
-       prs_uint32("level", ps, depth, &(q_u->level));
+       if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
+               return False;
+       if (!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
 
-       if (!ps->io)
-       {
-               /* writing */
-               buf_ptr = q_u->buffer != NULL ? 1 : 0;
-       }
-       prs_uint32("buffer pointer", ps, depth, &buf_ptr);
+       if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
+               return False;
 
-       if (buf_ptr != 0)
-       {
-               spoolss_io_read_buffer8("",ps, &q_u->buffer, &count,depth);
-       }
-       if (q_u->buffer != NULL)
-       {
-               free(q_u->buffer);
-       }
-       prs_uint32("buffer size", ps, depth, &(q_u->offered));  
+       if (!prs_align(ps))
+               return False;
+       if (!prs_uint32("offered", ps, depth, &q_u->offered))
+               return False;
 
-       return count == q_u->offered;
+       return True;
 }
 
 /*******************************************************************
@@ -3138,9 +2758,11 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de
        prs_debug(ps, depth, desc, "");
        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;
 }
@@ -3149,20 +2771,25 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de
 ********************************************************************/  
 BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
 {
-
        prs_debug(ps, depth, desc, "");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
-       prs_uint32("level", ps, depth, &(q_u->level));
+       if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
+               return False;
+       if(!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
        
-       spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+       if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+       if(!prs_uint32("offered", ps, depth, &q_u->offered))
+               return False;
 
        return True;
 }
@@ -3589,8 +3216,7 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
        prs_uint32("info level", ps, depth, &level);
        prs_uint32("useless", ps, depth, &useless);
                
-       switch (level)
-       {
+       switch (level) {
                /*
                 * level 0 is used by setprinter when managing the queue
                 * (hold, stop, start a queue)
@@ -3614,7 +3240,6 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
 ********************************************************************/  
 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
 {
-       uint32 useless;
        prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
        depth++;
 
@@ -3624,32 +3249,44 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct
         * the info level are handled in a nice way.
         */
 
-       prs_align(ps);  
-       prs_uint32("useless", ps, depth, &useless);
-       smb_io_unistr2("", &(q_u->server_name),True,ps,depth);
-       prs_align(ps);  
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
+               return False;
+       if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("info_level", ps, depth, &q_u->level))
+               return False;
        
-       prs_uint32("info_level", ps, depth, &(q_u->level));
-               
-       spool_io_printer_info_level("", &(q_u->info), ps, depth);
-               
-       /* the 4 unknown are all 0 */
+       if(!spool_io_printer_info_level("", &(q_u->info), ps, depth))
+               return False;
        
+       /* the 4 unknown are all 0 */
+
        /* 
         * en fait ils sont pas inconnu
         * par recoupement avec rpcSetPrinter
         * c'est le devicemode 
         * et le security descriptor.
         */
-               
-       prs_uint32("unk0", ps, depth, &(q_u->unk0));
-       prs_uint32("unk1", ps, depth, &(q_u->unk1));
-       prs_uint32("unk2", ps, depth, &(q_u->unk2));
-       prs_uint32("unk3", ps, depth, &(q_u->unk3));
-
-       prs_uint32("info_level", ps, depth, &(q_u->user_level));
        
-       spool_io_user_level("", &(q_u->user), ps, depth);
+       if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
+               return False;
+       if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
+               return False;
+       if(!prs_uint32("unk2", ps, depth, &q_u->unk2))
+               return False;
+       if(!prs_uint32("unk3", ps, depth, &q_u->unk3))
+               return False;
+
+       if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
+               return False;
+       if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
+               return False;
 
        return True;
 }
@@ -3676,52 +3313,71 @@ BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_
 {      
        SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
        
-       prs_debug(ps, depth, desc, "");
+       prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
        depth++;
                
        /* reading */
-       if (ps->io)
-       {
+       if (UNMARSHALLING(ps)) {
                il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
                ZERO_STRUCTP(il);
                *q_u=il;
-               DEBUG(1,("lecture: memoire ok\n"));
        }
-       else
-       {
+       else {
                il=*q_u;
        }
        
-       prs_align(ps);  
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("cversion",           ps, depth, &(il->cversion));
-       prs_uint32("name",               ps, depth, &(il->name_ptr));
-       prs_uint32("environment",        ps, depth, &(il->environment_ptr));
-       prs_uint32("driverpath",         ps, depth, &(il->driverpath_ptr));
-       prs_uint32("datafile",           ps, depth, &(il->datafile_ptr));
-       prs_uint32("configfile",         ps, depth, &(il->configfile_ptr));
-       prs_uint32("helpfile",           ps, depth, &(il->helpfile_ptr));
-       prs_uint32("monitorname",        ps, depth, &(il->monitorname_ptr));
-       prs_uint32("defaultdatatype",    ps, depth, &(il->defaultdatatype_ptr));
-       prs_uint32("dependentfilessize", ps, depth, &(il->dependentfilessize));
-       prs_uint32("dependentfiles",     ps, depth, &(il->dependentfiles_ptr));
+       if(!prs_uint32("cversion", ps, depth, &il->cversion))
+               return False;
+       if(!prs_uint32("name", ps, depth, &il->name_ptr))
+               return False;
+       if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
+               return False;
+       if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
+               return False;
+       if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
+               return False;
+       if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
+               return False;
+       if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
+               return False;
+       if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
+               return False;
+       if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
+               return False;
+       if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
+               return False;
+       if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
+               return False;
 
-       prs_align(ps);  
+       if(!prs_align(ps))
+               return False;
        
-       smb_io_unistr2("", &(il->name),            il->name_ptr,            ps, depth);
-       smb_io_unistr2("", &(il->environment),     il->environment_ptr,     ps, depth);
-       smb_io_unistr2("", &(il->driverpath),      il->driverpath_ptr,      ps, depth);
-       smb_io_unistr2("", &(il->datafile),        il->datafile_ptr,        ps, depth);
-       smb_io_unistr2("", &(il->configfile),      il->configfile_ptr,      ps, depth);
-       smb_io_unistr2("", &(il->helpfile),        il->helpfile_ptr,        ps, depth);
-       smb_io_unistr2("", &(il->monitorname),     il->monitorname_ptr,     ps, depth);
-       smb_io_unistr2("", &(il->defaultdatatype), il->defaultdatatype_ptr, ps, depth);
+       if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
+               return False;
 
-       prs_align(ps);  
+       if(!prs_align(ps))
+               return False;
+               
        if (il->dependentfiles_ptr)
                smb_io_buffer5("", &(il->dependentfiles), ps, depth);
 
-
        return True;
 }
 
@@ -3807,23 +3463,25 @@ BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
 ********************************************************************/  
 BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
 {
-       uint32 useless;
-       uint32 level;
-       prs_debug(ps, depth, desc, "");
+       prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
        depth++;
 
-       prs_align(ps);  
-       prs_uint32("info level", ps, depth, &level);
-       prs_uint32("useless", ps, depth, &useless);
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("level", ps, depth, &il->level))
+               return False;
+       if(!prs_uint32("ptr", ps, depth, &il->ptr))
+               return False;
+
+       if (il->ptr==0)
+               return True;
                
-       switch (level)
-       {
+       switch (il->level) {
                case 3:
                        spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth);
                        break;          
        }
 
-
        return True;
 }
 
@@ -3831,17 +3489,24 @@ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LE
 ********************************************************************/  
 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
 {
-       uint32 useless;
-       prs_debug(ps, depth, desc, "");
+       prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
        depth++;
 
-       prs_align(ps);  
-       prs_uint32("useless", ps, depth, &useless);
-       smb_io_unistr2("", &(q_u->server_name),True,ps,depth);
-       prs_align(ps);  
-       prs_uint32("info_level", ps, depth, &(q_u->level));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
+               return False;
+       if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
+               return False;
+               
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("info_level", ps, depth, &q_u->level))
+               return False;
 
-       spool_io_printer_driver_info_level("", &(q_u->info), ps, depth);
+       if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
+               return False;
 
        return True;
 }
@@ -3850,10 +3515,11 @@ BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, pr
 ********************************************************************/  
 BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
 {
-       prs_debug(ps, depth, desc, "");
+       prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
        depth++;
 
-       prs_uint32("status", ps, depth, &(q_u->status));
+       if(!prs_uint32("status", ps, depth, &q_u->status))
+               return False;
 
        return True;
 }
@@ -3944,104 +3610,70 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
 }
 
 /*******************************************************************
+ Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
 ********************************************************************/  
-BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
-{              
-       uint32 useless_ptr=0xADDE0FF0;
-       uint32 start_offset, end_offset, beginning;
-       uint32 bufsize_required=0;
-       
-       prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
+BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
+{
+       prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-
-       switch (r_u->level)
-       {
-               case 1:
-               {
-                       DRIVER_DIRECTORY_1 *driver_info_1;
-                       driver_info_1=&(r_u->ctr.driver.info_1);
-                       
-                       bufsize_required = size_of_relative_string(&(driver_info_1->name));
-                       break;
-               }
-       }
-       
-       DEBUG(4,("spoolss_io_r_getprinterdriverdir, size needed: %d\n",bufsize_required));
-       DEBUG(4,("spoolss_io_r_getprinterdriverdir, size offered: %d\n",r_u->offered));
-
-       /* check if the buffer is big enough for the datas */
-
-       if (r_u->offered<bufsize_required)
-       {       
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
+               return False;
+       if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
+               return False;
 
-               /* it's too small */
-               r_u->status=ERROR_INSUFFICIENT_BUFFER;  /* say so */
-               r_u->offered=0;                         /* don't send back the buffer */        
-               DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer too small\n"));
+       if(!prs_align(ps))
+               return False;
+               
+       if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
+               return False;
+       if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
+               return False;
+               
+       if(!prs_align(ps))
+               return False;
 
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-       }
-       else
-       {       
-               DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer large enough\n"));
-       
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-               beginning=prs_offset(ps);
-               start_offset=prs_offset(ps);
-               end_offset=start_offset+r_u->offered;
+       if(!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
                
-               switch (r_u->level)
-               {
-                       case 1:
-                       {
-                               DRIVER_DIRECTORY_1 *info;
-                               info = &(r_u->ctr.driver.info_1);
-                               prs_unistr("name", ps, depth, &(info->name));
-                               /*smb_io_printer_driver_dir_1(desc, info, ps, depth, &start_offset, &end_offset);*/
-                               break;
-                       }               
-               }               
-               prs_set_offset(ps, beginning+r_u->offered);
-               prs_align(ps);
-       }
-       
-       /*
-        * if the buffer was too small, send the minimum required size
-        * if it was too large, send the real needed size
-        */
-               
-       prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
+               return False;
+               
+       if(!prs_align(ps))
+               return False;
+               
+       if(!prs_uint32("offered", ps, depth, &q_u->offered))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
+ Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
 ********************************************************************/  
-BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
-{
-
-       uint32 useless_ptr=0xADDE0FF0;
-       prs_debug(ps, depth, desc, "");
+BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
+{              
+       prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
        depth++;
 
-       prs_align(ps);
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-       smb_io_unistr2("", &(q_u->name),True,ps,depth); 
-       prs_align(ps);
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-       smb_io_unistr2("", &(q_u->environment),True,ps,depth);
-       prs_align(ps);
-       prs_uint32("level", ps, depth, &(q_u->level));
-       spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
-       prs_align(ps);
-       prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+       if (!prs_align(ps))
+               return False;
+               
+       if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
+               return False;
 
-       return True;
+       if (!prs_align(ps))
+               return False;
+               
+       if (!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
+               
+       if (!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;            
 }
 
 /*******************************************************************
@@ -4295,23 +3927,23 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
 ********************************************************************/  
 static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
 {
-       prs_debug(ps, depth, desc, "spoolss_io_addform");
-       depth++;
-       prs_align(ps);
-
-       if (ptr!=0)
-       {
-              prs_uint32("flags",    ps, depth, &(f->flags));
-              prs_uint32("name_ptr", ps, depth, &(f->name_ptr));
-              prs_uint32("size_x",   ps, depth, &(f->size_x));
-              prs_uint32("size_y",   ps, depth, &(f->size_y));
-              prs_uint32("left",     ps, depth, &(f->left));
-              prs_uint32("top",      ps, depth, &(f->top));
-              prs_uint32("right",    ps, depth, &(f->right));
-              prs_uint32("bottom",   ps, depth, &(f->bottom));
+       prs_debug(ps, depth, desc, "spoolss_io_addform");
+       depth++;
+       prs_align(ps);
 
-              smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth);
-       }
+       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);
+       }
 
        return True;
 }
@@ -4320,20 +3952,20 @@ static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps,
 ********************************************************************/  
 BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
 {
-       uint32 useless_ptr=0;
-       prs_debug(ps, depth, desc, "spoolss_io_q_addform");
-       depth++;
+       uint32 useless_ptr=0;
+       prs_debug(ps, depth, desc, "spoolss_io_q_addform");
+       depth++;
 
-       prs_align(ps);
-       smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth);
-       prs_uint32("level",  ps, depth, &(q_u->level));
-       prs_uint32("level2", ps, depth, &(q_u->level2));
+       prs_align(ps);
+       smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth);
+       prs_uint32("level",  ps, depth, &(q_u->level));
+       prs_uint32("level2", ps, depth, &(q_u->level2));
 
-       if (q_u->level==1)
-       {
-              prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
-              spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
-       }
+       if (q_u->level==1)
+       {
+               prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
+               spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
+       }
 
        return True;
 }
@@ -4342,11 +3974,11 @@ BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int
 ********************************************************************/  
 BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
 {
-       prs_debug(ps, depth, desc, "spoolss_io_r_addform");
-       depth++;
+       prs_debug(ps, depth, desc, "spoolss_io_r_addform");
+       depth++;
 
-       prs_align(ps);
-       prs_uint32("status",    ps, depth, &(r_u->status));
+       prs_align(ps);
+       prs_uint32("status",    ps, depth, &(r_u->status));
 
        return True;
 }
@@ -4391,134 +4023,57 @@ BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int
 }
 
 /*******************************************************************
+ Parse a SPOOL_R_GETJOB structure.
 ********************************************************************/  
 BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
 {              
-       uint32 useless_ptr=0xADDE0FF0;
-       uint32 start_offset, end_offset, beginning;
-       uint32 bufsize_required=0;
-       
        prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("pointer", ps, depth, &useless_ptr);
-
-       switch (r_u->level)
-       {
-               case 1:
-               {
-                       JOB_INFO_1 *info;
-                       info=r_u->ctr.job.job_info_1;
-                       
-                       bufsize_required += spoolss_size_job_info_1(info);
-                       break;
-               }
-               case 2:
-               {
-                       JOB_INFO_2 *info;
-                       info=r_u->ctr.job.job_info_2;
-                       
-                       bufsize_required += spoolss_size_job_info_2(info);
-                       break;
-               }       
-       }
-       
-       DEBUG(4,("spoolss_io_r_getjob, size needed: %d\n",bufsize_required));
-       DEBUG(4,("spoolss_io_r_getjob, size offered: %d\n",r_u->offered));
-
-       /* check if the buffer is big enough for the datas */
-       if (r_u->offered<bufsize_required)
-       {       
-               /* it's too small */
-               r_u->status=ERROR_INSUFFICIENT_BUFFER;  /* say so */
-               r_u->offered=0;                         /* don't send back the buffer */
+       if (!prs_align(ps))
+               return False;
                
-               DEBUG(4,("spoolss_io_r_getjob, buffer too small\n"));
+       if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
+               return False;
 
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-       }
-       else
-       {       
-               DEBUG(4,("spoolss_io_r_enumjobs, buffer large enough\n"));
-       
-               prs_uint32("size of buffer", ps, depth, &(r_u->offered));
-               beginning=prs_offset(ps);
-               start_offset=prs_offset(ps);
-               end_offset=start_offset+r_u->offered;
+       if (!prs_align(ps))
+               return False;
                
-               switch (r_u->level)
-               {
-                       case 1:
-                       {
-                               JOB_INFO_1 *info;
-                               info = r_u->ctr.job.job_info_1;
-                               smb_io_job_info_1(desc, info, ps, depth, &start_offset, &end_offset);
-                               break;
-                       }
-                       case 2:
-                       {
-                               JOB_INFO_2 *info;
-                               info = r_u->ctr.job.job_info_2;
-                               smb_io_job_info_2(desc, info, ps, depth, &start_offset, &end_offset);
-                               break;
-                       }
+       if (!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
                
-               }               
-               prs_set_offset(ps, beginning+r_u->offered);
-               prs_align(ps);
-       }
-       
-       /*
-        * if the buffer was too small, send the minimum required size
-        * if it was too large, send the real needed size
-        */
-               
-       prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
+       if (!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
-/****************************************************************************
-****************************************************************************/
-void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u)
-{      
-       switch (r_u->level)
-       {
-               case 1:
-               {
-                       free(r_u->ctr.job.job_info_1);
-                       break;
-               }
-               case 2:
-               {
-                       free_job_info_2(r_u->ctr.job.job_info_2);
-                       break;
-               }
-       }
+       return True;            
 }
 
 /*******************************************************************
+ Parse a SPOOL_Q_GETJOB structure.
 ********************************************************************/  
 BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
 {
-
        prs_debug(ps, depth, desc, "");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
-       prs_uint32("jobid", ps, depth, &(q_u->jobid));
-       prs_uint32("level", ps, depth, &(q_u->level));
+       if(!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth))
+               return False;
+       if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
+               return False;
+       if(!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
        
-       spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+       if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+       if(!prs_uint32("offered", ps, depth, &q_u->offered))
+               return False;
 
        return True;
 }
index 50b6dd38460520ce170fcda465d265e984fa37db..4965542d73ebae9f56b27a00d8c52cd97afe4f46 100755 (executable)
@@ -42,17 +42,15 @@ static BOOL api_spoolss_open_printer_ex(uint16 vuid, prs_struct *data, prs_struc
                DEBUG(0,("spoolss_io_q_open_printer_ex: unable to unmarshall SPOOL_Q_OPEN_PRINTER_EX.\n"));
                return False;
        }
-       
+
        if (q_u.printername_ptr != 0)
-       {
                printername = &q_u.printername;
-       }
-       
+
        r_u.status = _spoolss_open_printer_ex( printername,
                                               &q_u.printer_default,
                                               q_u.user_switch, q_u.user_ctr,
                                               &r_u.handle);
-                                              
+
        if (!spoolss_io_r_open_printer_ex("",&r_u,rdata,0)){
                DEBUG(0,("spoolss_io_r_open_printer_ex: unable to marshall SPOOL_R_OPEN_PRINTER_EX.\n"));
                return False;
@@ -88,9 +86,9 @@ static BOOL api_spoolss_getprinterdata(uint16 vuid, prs_struct *data, prs_struct
                DEBUG(0,("spoolss_io_r_getprinterdata: unable to marshall SPOOL_R_GETPRINTERDATA.\n"));
                return False;
        }
-       
+
        safe_free(r_u.data);
-       
+
        return True;
 }
 
@@ -111,7 +109,7 @@ static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct *
                DEBUG(0,("spoolss_io_q_closeprinter: unable to unmarshall SPOOL_Q_CLOSEPRINTER.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_closeprinter(&q_u.handle);
        memcpy(&r_u.handle, &q_u.handle, sizeof(r_u.handle));
 
@@ -119,6 +117,8 @@ static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct *
                DEBUG(0,("spoolss_io_r_closeprinter: unable to marshall SPOOL_R_CLOSEPRINTER.\n"));
                return False;
        }
+
+       return True;
 }
 
 /********************************************************************
@@ -141,11 +141,13 @@ static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat
        r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags,
                                       q_u.options, &q_u.localmachine,
                                       q_u.printerlocal, &q_u.option);
-                                      
+
        if (!spoolss_io_r_rffpcnex("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n"));
                return False;
        }
+
+       return True;
 }
 
 
@@ -170,11 +172,13 @@ static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat
 
        r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change,
                                       &q_u.option, &r_u.count, &r_u.info);
-                                      
+
        if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) {
                DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n"));
                return False;
        }
+
+       return True;
 }
 
 
@@ -191,8 +195,6 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct *
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
-       DEBUG(5,("api_spoolss_enumprinters\n"));
-
        new_spoolss_allocate_buffer(&q_u.buffer);
 
        if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) {
@@ -206,7 +208,7 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct *
        r_u.status = _spoolss_enumprinters( q_u.flags, &q_u.servername, q_u.level,
                                            r_u.buffer, q_u.offered,
                                            &r_u.needed, &r_u.returned);
-       
+
        if (!new_spoolss_io_r_enumprinters("", &r_u, rdata, 0)) {
                DEBUG(0,("new_spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n"));
                new_spoolss_free_buffer(q_u.buffer);
@@ -214,7 +216,7 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct *
        }
 
        new_spoolss_free_buffer(q_u.buffer);
-       
+
        return True;
 }
 
@@ -231,24 +233,27 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
+       new_spoolss_allocate_buffer(&q_u.buffer);
+
        if(!spoolss_io_q_getprinter("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n"));
                return False;
        }
 
-       r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level,
-                                       &r_u.ctr, &q_u.offered, &r_u.needed);
+       /* that's an [in out] buffer */
+       new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
 
-       memcpy(&r_u.handle, &q_u.handle, sizeof(&r_u.handle));
-       r_u.offered = q_u.offered;
-       r_u.level = q_u.level;
-       safe_free(q_u.buffer);
+       r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level,
+                                        r_u.buffer, q_u.offered, 
+                                        &r_u.needed);
 
        if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n"));
+               new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
-       
+
+       new_spoolss_free_buffer(q_u.buffer);
        return True;
 }
 
@@ -265,26 +270,28 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str
 
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
+       new_spoolss_allocate_buffer(&q_u.buffer);
+
        if(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n"));
                return False;
        }
-       
-       r_u.status = _spoolss_getprinterdriver2(&q_u.handle,
-                               &q_u.architecture, q_u.level,
-                               &r_u.ctr, &q_u.buf_size,
-                               &r_u.needed);
-       
-       r_u.offered = q_u.buf_size;
-       r_u.level = q_u.level;
-       spoolss_io_free_buffer(&(q_u.buffer));
 
+       /* that's an [in out] buffer */
+       new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
+
+       r_u.status = _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture, q_u.level, q_u.unknown,
+                                               r_u.buffer, q_u.offered,
+                                               &r_u.needed, &r_u.unknown0, &r_u.unknown1);
+       
        if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n"));
+               new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
        
+       new_spoolss_free_buffer(q_u.buffer);
        return True;
 }
 
@@ -300,20 +307,20 @@ static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_stru
 
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_startpageprinter("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_startpageprinter: unable to unmarshall SPOOL_Q_STARTPAGEPRINTER.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_startpageprinter(&q_u.handle);
-       
+
        if(!spoolss_io_r_startpageprinter("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_startpageprinter: unable to marshall SPOOL_R_STARTPAGEPRINTER.\n"));
                return False;
        }
-       
-       return True;    
+
+       return True;
 }
 
 
@@ -329,58 +336,53 @@ static BOOL api_spoolss_endpageprinter(uint16 vuid, prs_struct *data, prs_struct
 
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_endpageprinter("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_endpageprinter: unable to unmarshall SPOOL_Q_ENDPAGEPRINTER.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_endpageprinter(&q_u.handle);
-       
+
        if(!spoolss_io_r_endpageprinter("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_endpageprinter: unable to marshall SPOOL_R_ENDPAGEPRINTER.\n"));
                return False;
        }
-       
+
        return True;
 }
 
 /********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
+********************************************************************/
 static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SPOOL_Q_STARTDOCPRINTER q_u;
        SPOOL_R_STARTDOCPRINTER r_u;
-       
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_startdocprinter("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_startdocprinter: unable to unmarshall SPOOL_Q_STARTDOCPRINTER.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_startdocprinter(&q_u.handle,
                                  q_u.doc_info_container.level,
                                  &q_u.doc_info_container.docinfo,
                                  &r_u.jobid);
-       
+
        if(!spoolss_io_r_startdocprinter("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_startdocprinter: unable to marshall SPOOL_R_STARTDOCPRINTER.\n"));
                return False;
        }
-       
+
        return True;
 }
 
+
 /********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
+********************************************************************/
 static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SPOOL_Q_ENDDOCPRINTER q_u;
@@ -388,28 +390,25 @@ static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct
 
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_enddocprinter("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_enddocprinter: unable to unmarshall SPOOL_Q_ENDDOCPRINTER.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_enddocprinter(&q_u.handle);
-       
+
        if(!spoolss_io_r_enddocprinter("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_enddocprinter: unable to marshall SPOOL_R_ENDDOCPRINTER.\n"));
                return False;
        }
-       
+
        return True;            
 }
 
 
 /********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
+********************************************************************/
 static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SPOOL_Q_WRITEPRINTER q_u;
@@ -417,19 +416,19 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *
 
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_writeprinter("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_writeprinter: unable to unmarshall SPOOL_Q_WRITEPRINTER.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_writeprinter(&q_u.handle,
                                           q_u.buffer_size,
                                           q_u.buffer,
                                           &q_u.buffer_size2);
        r_u.buffer_written = q_u.buffer_size2;
        safe_free(q_u.buffer);
-       
+
        if(!spoolss_io_r_writeprinter("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_writeprinter: unable to marshall SPOOL_R_WRITEPRINTER.\n"));
                return False;
@@ -439,6 +438,9 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *
 }
 
 /****************************************************************************
+
+FIX ME: JFM: freeing memory ????
+
 ****************************************************************************/
 static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
@@ -483,9 +485,9 @@ static BOOL api_spoolss_fcpn(uint16 vuid, prs_struct *data, prs_struct *rdata)
                DEBUG(0,("spoolss_io_q_fcpn: unable to unmarshall SPOOL_Q_FCPN.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_fcpn(&q_u.handle);
-       
+
        if(!spoolss_io_r_fcpn("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_fcpn: unable to marshall SPOOL_R_FCPN.\n"));
                return False;
@@ -501,25 +503,30 @@ static BOOL api_spoolss_addjob(uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SPOOL_Q_ADDJOB q_u;
        SPOOL_R_ADDJOB r_u;
-       
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
+       new_spoolss_allocate_buffer(&q_u.buffer);
+
        if(!spoolss_io_q_addjob("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_addjob: unable to unmarshall SPOOL_Q_ADDJOB.\n"));
                return False;
        }
 
+       /* that's only an [in] buffer ! */
+
        r_u.status = _spoolss_addjob(&q_u.handle, q_u.level,
-                                    &q_u.buffer, q_u.buf_size);
-       
-       spoolss_io_free_buffer(&(q_u.buffer));
-       
+                                    q_u.buffer, q_u.offered);
+               
        if(!spoolss_io_r_addjob("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_addjob: unable to marshall SPOOL_R_ADDJOB.\n"));
+               new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
 
+       new_spoolss_free_buffer(q_u.buffer);
+
        return True;            
 }
 
@@ -555,7 +562,7 @@ static BOOL api_spoolss_enumjobs(uint16 vuid, prs_struct *data, prs_struct *rdat
        }
 
        new_spoolss_free_buffer(q_u.buffer);
-       
+
        return True;
 }
 
@@ -566,22 +573,22 @@ static BOOL api_spoolss_schedulejob(uint16 vuid, prs_struct *data, prs_struct *r
 {
        SPOOL_Q_SCHEDULEJOB q_u;
        SPOOL_R_SCHEDULEJOB r_u;
-       
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_schedulejob("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_schedulejob: unable to unmarshall SPOOL_Q_SCHEDULEJOB.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_schedulejob(&q_u.handle, q_u.jobid);
-       
+
        if(!spoolss_io_r_schedulejob("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_schedulejob: unable to marshall SPOOL_R_SCHEDULEJOB.\n"));
                return False;
        }
-       
+
        return True;
 }
 
@@ -591,23 +598,23 @@ static BOOL api_spoolss_setjob(uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SPOOL_Q_SETJOB q_u;
        SPOOL_R_SETJOB r_u;
-       
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
-       
+
        if(!spoolss_io_q_setjob("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_setjob: unable to unmarshall SPOOL_Q_SETJOB.\n"));
                return False;
        }
-       
+
        r_u.status = _spoolss_setjob(&q_u.handle, q_u.jobid,
                                q_u.level, &q_u.ctr, q_u.command);
-                               
+
        if(!spoolss_io_r_setjob("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_setjob: unable to marshall SPOOL_R_SETJOB.\n"));
                return False;
        }
-       
+
        return True;
 }
 
@@ -618,7 +625,7 @@ static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_st
 {
        SPOOL_Q_ENUMPRINTERDRIVERS q_u;
        SPOOL_R_ENUMPRINTERDRIVERS r_u;
-       
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
@@ -643,7 +650,7 @@ static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_st
        }
 
        new_spoolss_free_buffer(q_u.buffer);
-       
+
        return True;
 }
 
@@ -654,7 +661,7 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda
 {
        SPOOL_Q_ENUMFORMS q_u;
        SPOOL_R_ENUMFORMS r_u;
-               
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
@@ -667,7 +674,7 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda
 
        /* that's an [in out] buffer */
        new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-       
+
        r_u.status = _new_spoolss_enumforms(&q_u.handle, q_u.level, 
                                r_u.buffer, q_u.offered,
                                &r_u.needed, &r_u.numofforms);
@@ -677,9 +684,9 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda
                new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
-       
+
        new_spoolss_free_buffer(q_u.buffer);
-       
+
        return True;
 }
 
@@ -690,7 +697,7 @@ static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rda
 {
        SPOOL_Q_ENUMPORTS q_u;
        SPOOL_R_ENUMPORTS r_u;
-       
+
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
@@ -703,19 +710,19 @@ static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rda
 
        /* that's an [in out] buffer */
        new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-       
+
        r_u.status = _spoolss_enumports(&q_u.name, q_u.level,
                                        r_u.buffer, q_u.offered,
                                        &r_u.needed, &r_u.returned);
-       
+
        if (!new_spoolss_io_r_enumports("",&r_u,rdata,0)) {
                DEBUG(0,("new_spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n"));
                new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
-       
+
        new_spoolss_free_buffer(q_u.buffer);
-       
+
        return True;
 }
 
@@ -738,7 +745,7 @@ static BOOL api_spoolss_addprinterex(uint16 vuid, prs_struct *data, prs_struct *
        r_u.status = _spoolss_addprinterex(&q_u.server_name,
                                q_u.level, &q_u.info,
                                q_u.unk0, q_u.unk1, q_u.unk2, q_u.unk3,
-                               q_u.user_level, &q_u.user,
+                               q_u.user_switch, &q_u.user_ctr,
                                &r_u.handle);
                                
        if(!spoolss_io_r_addprinterex("", &r_u, rdata, 0)) {
@@ -764,8 +771,7 @@ static BOOL api_spoolss_addprinterdriver(uint16 vuid, prs_struct *data, prs_stru
                return False;
        }
        
-       r_u.status = _spoolss_addprinterdriver(&q_u.server_name,
-                               q_u.level, &q_u.info);
+       r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info);
                                
        if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) {
                DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n"));
@@ -781,26 +787,32 @@ static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data,
 {
        SPOOL_Q_GETPRINTERDRIVERDIR q_u;
        SPOOL_R_GETPRINTERDRIVERDIR r_u;
-       
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       new_spoolss_allocate_buffer(&q_u.buffer);
+
        if(!spoolss_io_q_getprinterdriverdir("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_getprinterdriverdir: unable to unmarshall SPOOL_Q_GETPRINTERDRIVERDIR.\n"));
                return False;
        }
-       
-       r_u.offered = q_u.buf_size;
-       r_u.level = q_u.level;
-       r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name,
-                               &q_u.environment,
-                               q_u.level,
-                               &r_u.ctr,
-                               &r_u.offered);
-       spoolss_io_free_buffer(&q_u.buffer);
-       
+
+       /* that's an [in out] buffer */
+       new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
+
+       r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name, &q_u.environment, q_u.level,
+                                                       r_u.buffer, q_u.offered,
+                                                       &r_u.needed);
+
        if(!spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0)) {
                DEBUG(0,("spoolss_io_r_getprinterdriverdir: unable to marshall SPOOL_R_GETPRINTERDRIVERDIR.\n"));
+               new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
-       
+
+       new_spoolss_free_buffer(q_u.buffer);
+
        return True;
 }
 
@@ -909,8 +921,7 @@ static BOOL api_spoolss_setform(uint16 vuid, prs_struct *data, prs_struct *rdata
                return False;
        }
        
-       r_u.status = _spoolss_setform(&q_u.handle,
-                                     &q_u.name, q_u.level, &q_u.form);
+       r_u.status = _spoolss_setform(&q_u.handle, &q_u.name, q_u.level, &q_u.form);
                                      
        if(!spoolss_io_r_setform("", &r_u, rdata, 0)) {
                DEBUG(0,("spoolss_io_r_setform: unable to marshall SPOOL_R_SETFORM.\n"));
@@ -997,27 +1008,27 @@ static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata)
        SPOOL_Q_GETJOB q_u;
        SPOOL_R_GETJOB r_u;
        
+       new_spoolss_allocate_buffer(&q_u.buffer);
+
        if(!spoolss_io_q_getjob("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n"));
                return False;
        }
 
-       r_u.offered = q_u.buf_size;
-       r_u.level = q_u.level;
-       r_u.status = _spoolss_getjob(&q_u.handle,
-                               q_u.jobid,
-                               q_u.level,
-                               &r_u.ctr,
-                               &r_u.offered);
-       spoolss_io_free_buffer(&(q_u.buffer));
+       /* that's an [in out] buffer */
+       new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
+
+       r_u.status = _spoolss_getjob(&q_u.handle, q_u.jobid, q_u.level,
+                                       r_u.buffer, q_u.offered,
+                                       &r_u.needed);
        
        if(!spoolss_io_r_getjob("",&r_u,rdata,0)) {
                DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n"));
+               new_spoolss_free_buffer(q_u.buffer);
                return False;
        }
-       
-       free_spoolss_r_getjob(&r_u);
-       
+               
+       new_spoolss_free_buffer(q_u.buffer);
        return True;
 }
 
index 2e80cbdbf6ffccf1053c7e6c1743e1ec34e00f6e..90a7b44aef3efecb3206c0e7cd01efaef1f78a3a 100644 (file)
@@ -392,7 +392,6 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
                                 uint32  user_switch, SPOOL_USER_CTR user_ctr,
                                 POLICY_HND *handle)
 {
-       BOOL printer_open = False;
        fstring name;
        fstring datatype;
        
@@ -439,57 +438,41 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
        return NT_STATUS_NO_PROBLEMO;
 }
 
+/****************************************************************************
+****************************************************************************/
 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
-                          NT_PRINTER_INFO_LEVEL *printer,
-                         uint32 level)
+                               NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
-       switch (level)
-       {
+       switch (level) {
                case 2: 
-               {
-                       uni_2_asc_printer_info_2(uni->info_2,
-                                                &(printer->info_2));
+                       uni_2_asc_printer_info_2(uni->info_2, &(printer->info_2));
                        break;
-               }
                default:
                        break;
        }
-       
-
 
        return True;
 }
 
 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
-                                 NT_PRINTER_DRIVER_INFO_LEVEL *printer,
-                                uint32 level)
+                                       NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
 {
-       switch (level)
-       {
+       switch (level) {
                case 3: 
-               {
                        printer->info_3=NULL;
                        uni_2_asc_printer_driver_3(uni->info_3, &(printer->info_3));                                            
                        break;
-               }
                default:
                        break;
        }
-       
-
 
        return True;
 }
 
 static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode)
 {
-       unistr_to_ascii(nt_devmode->devicename,
-                       devmode.devicename.buffer,
-                       31);
-
-       unistr_to_ascii(nt_devmode->formname,
-                       devmode.formname.buffer,
-                       31);
+       unistr_to_ascii(nt_devmode->devicename, devmode.devicename.buffer, 31);
+       unistr_to_ascii(nt_devmode->formname, devmode.formname.buffer, 31);
 
        nt_devmode->specversion=devmode.specversion;
        nt_devmode->driverversion=devmode.driverversion;
@@ -524,7 +507,7 @@ static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode)
        nt_devmode->reserved2=devmode.reserved2;
        nt_devmode->panningwidth=devmode.panningwidth;
        nt_devmode->panningheight=devmode.panningheight;
-       
+
        if (nt_devmode->driverextra != 0) 
        {
                /* if we had a previous private delete it and make a new one */
@@ -533,7 +516,6 @@ static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode)
                nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8));
                memcpy(nt_devmode->private, devmode.private, nt_devmode->driverextra);
        }
-       
 
        return True;
 }
@@ -1948,65 +1930,121 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_getprinter( POLICY_HND *handle,
-                               uint32 level,
-                               PRINTER_INFO *ctr,
-                               uint32 *offered,
-                               uint32 *needed)
+static uint32 getprinter_level_0(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
-       int snum;
-       pstring servername;
+       PRINTER_INFO_0 *printer=NULL;
+
+       printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0));
+       construct_printer_info_0(printer, snum, servername);
        
-       pstrcpy(servername, global_myname);
+       /* check the required size. */  
+       *needed += spoolss_size_printer_info_0(printer);
 
-       if (!get_printer_snum(handle,&snum))
-       {
-               return NT_STATUS_INVALID_HANDLE;
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       /* fill the buffer with the structures */
+       new_smb_io_printer_info_0("", buffer, printer, 0);      
+       
+       /* clear memory */
+       safe_free(printer);
+
+       if (*needed > offered) {
+               return ERROR_INSUFFICIENT_BUFFER;
        }
+       else
+               return NT_STATUS_NO_PROBLEMO;   
+}
 
-       DEBUG(0,("_spoolss_getprinter: offered and needed params ignored\n"));
+/****************************************************************************
+****************************************************************************/
+static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       PRINTER_INFO_1 *printer=NULL;
 
-       switch (level)
-       {
-               case 0:
-               { 
-                       PRINTER_INFO_0 *printer;
-                       
-                       printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0));
-                       construct_printer_info_0(printer, snum, servername);
-                       ctr->printer.info0=printer;
-                       
-                       return 0x0;
-               }
-               case 1:
-               {
-                       PRINTER_INFO_1 *printer;
-                       
-                       printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1));
-                       construct_printer_info_1(printer, snum, servername);
-                       ctr->printer.info1=printer;                     
+       printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1));
+       construct_printer_info_1(printer, snum, servername);
+       
+       /* check the required size. */  
+       *needed += spoolss_size_printer_info_1(printer);
 
-                       return 0x0;
-               }
-               case 2:
-               {
-                       PRINTER_INFO_2 *printer;
-                       
-                       printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));        
-                       construct_printer_info_2(printer, snum, servername);
-                       ctr->printer.info2=printer;     
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
 
-                       return 0x0;
-               }
-               default:
-               {
-                       break;
-               }
+       /* fill the buffer with the structures */
+       new_smb_io_printer_info_1("", buffer, printer, 0);      
+       
+       /* clear memory */
+       safe_free(printer);
+
+       if (*needed > offered) {
+               return ERROR_INSUFFICIENT_BUFFER;
        }
+       else
+               return NT_STATUS_NO_PROBLEMO;   
+}
 
-       return NT_STATUS_INVALID_INFO_CLASS;
+/****************************************************************************
+****************************************************************************/
+static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       PRINTER_INFO_2 *printer=NULL;
+
+       printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));        
+       construct_printer_info_2(printer, snum, servername);
+       
+       /* check the required size. */  
+       *needed += spoolss_size_printer_info_2(printer);
+
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       /* fill the buffer with the structures */
+       new_smb_io_printer_info_2("", buffer, printer, 0);      
+       
+       /* clear memory */
+       safe_free(printer);
+
+       if (*needed > offered) {
+               return ERROR_INSUFFICIENT_BUFFER;
+       }
+       else
+               return NT_STATUS_NO_PROBLEMO;   
 }
 
+/****************************************************************************
+****************************************************************************/
+uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
+                          NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       int snum;
+       pstring servername;
+       
+       *needed=0;
+
+       pstrcpy(servername, global_myname);
+
+       if (!get_printer_snum(handle, &snum))
+       {
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       switch (level) {
+       case 0:
+               return getprinter_level_0(servername, snum, buffer, offered, needed);
+               break;
+       case 1:
+               return getprinter_level_1(servername,snum, buffer, offered, needed);
+               break;
+       case 2:         
+               return getprinter_level_2(servername,snum, buffer, offered, needed);
+               break;
+       default:
+               return NT_STATUS_INVALID_LEVEL;
+               break;
+       }
+}      
+               
 /********************************************************************
  * construct_printer_driver_info_1
  * fill a construct_printer_driver_info_1 struct
@@ -2187,63 +2225,129 @@ static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum,
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle,
-                               const UNISTR2 *uni_arch,
-                               uint32 level,
-                               DRIVER_INFO *ctr,
-                               uint32 *offered,
-                               uint32 *needed)
+static uint32 getprinterdriver2_level1(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       DRIVER_INFO_1 *info=NULL;
+       
+       info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1));
+       
+       construct_printer_driver_info_1(info, snum, servername, architecture);
+
+       /* check the required size. */  
+       *needed += spoolss_size_printer_driver_info_1(info);
+
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       /* fill the buffer with the structures */
+       new_smb_io_printer_driver_info_1("", buffer, info, 0);  
+
+       /* clear memory */
+       safe_free(info);
+
+       if (*needed > offered) {
+               return ERROR_INSUFFICIENT_BUFFER;
+       }
+       else
+               return NT_STATUS_NO_PROBLEMO;
+}
+
+/****************************************************************************
+****************************************************************************/
+static uint32 getprinterdriver2_level2(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       DRIVER_INFO_2 *info=NULL;
+       
+       info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2));
+       
+       construct_printer_driver_info_2(info, snum, servername, architecture);
+
+       /* check the required size. */  
+       *needed += spoolss_size_printer_driver_info_2(info);
+
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       /* fill the buffer with the structures */
+       new_smb_io_printer_driver_info_2("", buffer, info, 0);  
+
+       /* clear memory */
+       safe_free(info);
+
+       if (*needed > offered) {
+               return ERROR_INSUFFICIENT_BUFFER;
+       }
+       else
+               return NT_STATUS_NO_PROBLEMO;
+}
+
+/****************************************************************************
+****************************************************************************/
+static uint32 getprinterdriver2_level3(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       DRIVER_INFO_3 *info=NULL;
+       
+       info=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3));
+       
+       construct_printer_driver_info_3(info, snum, servername, architecture);
+
+       /* check the required size. */  
+       *needed += spoolss_size_printer_driver_info_3(info);
+
+       if (!alloc_buffer_size(buffer, *needed))
+               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);
+
+       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,
+                               NEW_BUFFER *buffer, uint32 offered,
+                               uint32 *needed, uint32 *unknown0, uint32 *unknown1)
 {
        pstring servername;
        fstring architecture;
        int snum;
-       DRIVER_INFO_1 *info1=NULL;
-       DRIVER_INFO_2 *info2=NULL;
-       DRIVER_INFO_3 *info3=NULL;
+
+       DEBUG(4,("_spoolss_getprinterdriver2\n"));
+
+       *needed=0;
+       *unknown0=0;
+       *unknown1=0;
 
        pstrcpy(servername, global_myname);
+       unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
 
-       if (!get_printer_snum(handle,&snum))
+       if (!get_printer_snum(handle, &snum))
        {
                return NT_STATUS_INVALID_HANDLE;
        }
 
-       unistr2_to_ascii(architecture, uni_arch, sizeof(architecture) );
-       
-       DEBUG(1,("spoolss_getprinterdriver2:[%d]\n", level));
-       
-       switch (level)
-       {
-               case 1:
-               {                       
-                       info1=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1));
-                       construct_printer_driver_info_1(info1, snum, servername, architecture);
-                       ctr->driver.info1=info1;                        
-
-                       return 0x0;
-               }
-               case 2:
-               {
-                       info2=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2));
-                       construct_printer_driver_info_2(info2, snum, servername, architecture);
-                       ctr->driver.info2=info2;                        
-
-                       return 0x0;
-               }
-               case 3:
-               {
-                       info3=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3));
-                       construct_printer_driver_info_3(info3, snum, servername, architecture);
-                       ctr->driver.info3=info3;
-
-                       return 0x0;
-               }
-               default:
-               {
-                       break;
-               }
+       switch (level) {
+       case 1:
+               return getprinterdriver2_level1(servername, architecture, snum, buffer, offered, needed);
+               break;
+       case 2:
+               return getprinterdriver2_level2(servername, architecture, snum, buffer, offered, needed);
+               break;                          
+       case 3:
+               return getprinterdriver2_level3(servername, architecture, snum, buffer, offered, needed);
+               break;                          
+       default:
+               return NT_STATUS_INVALID_LEVEL;
+               break;
        }
-       return NT_STATUS_INVALID_INFO_CLASS;
 }
 
 /****************************************************************************
@@ -2617,10 +2721,9 @@ uint32 _spoolss_fcpn( const POLICY_HND *handle)
 /****************************************************************************
 ****************************************************************************/
 uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level,
-                               const BUFFER *buffer,
-                               uint32 buf_size)
+                       NEW_BUFFER *buffer, uint32 offered)
 {
-       return 0x0;
+       return NT_STATUS_NO_PROBLEMO;
 }
 
 /****************************************************************************
@@ -3273,7 +3376,7 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
                           NEW_BUFFER *buffer, uint32 offered, 
                           uint32 *needed, uint32 *returned)
 {
-       DEBUG(4,("spoolss_enumports\n"));
+       DEBUG(4,("_spoolss_enumports\n"));
        
        *returned=0;
        *needed=0;
@@ -3293,30 +3396,23 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_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_level,
-                               const SPOOL_USER_LEVEL *user,
+                               uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
+                               uint32 user_switch, const  SPOOL_USER_CTR *user,
                                POLICY_HND *handle)
 {
        NT_PRINTER_INFO_LEVEL printer;  
-       fstring ascii_name;
-       fstring server_name;
+       fstring name;
        fstring share_name;
-       UNISTR2 *portname;
-       SPOOL_PRINTER_INFO_LEVEL_2 *info2;
-       uint32 status = 0x0;
-       
-       if (!open_printer_hnd(handle))
-       {
-               return NT_STATUS_ACCESS_DENIED;
-       }
 
+       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;
@@ -3324,31 +3420,31 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name,
        /* convert from UNICODE to ASCII */
        convert_printer_info(info, &printer, level);
 
-       /* write the ASCII on disk */
-       status = add_a_printer(printer, level);
-       if (status != 0x0)
-       {
-               close_printer_handle(handle);
-               return status;
-       }
+       unistr2_to_ascii(share_name, &((info->info_2)->portname), sizeof(share_name)-1);
+       
+       slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
+
+       create_printer_hnd(handle);
 
-       info2=info->info_2;
-       portname=&(info2->portname);
+       open_printer_hnd(handle);
 
-       StrnCpy(server_name, global_myname, strlen(global_myname) );
-       unistr2_to_ascii(share_name, portname, sizeof(share_name)-1);
+       if (!set_printer_hnd_printertype(handle, name)) {
+               close_printer_handle(handle);
+               return NT_STATUS_ACCESS_DENIED;
+       }
        
-       slprintf(ascii_name, sizeof(ascii_name)-1, "\\\\%s\\%s", 
-                server_name, share_name);
-               
-       if (!set_printer_hnd_printertype(handle, ascii_name) ||
-           !set_printer_hnd_printername(handle, ascii_name))
-       {
+       if (!set_printer_hnd_printername(handle, name)) {
                close_printer_handle(handle);
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       return 0x0;
+       /* 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;
 }
 
 /****************************************************************************
@@ -3358,35 +3454,77 @@ uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
                                const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
 {
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
+       
        convert_printer_driver_info(info, &driver, level);
-       return add_a_printer_driver(driver, level);
+
+       if (add_a_printer_driver(driver, level)!=0)
+               return NT_STATUS_ACCESS_DENIED;
+
+       return NT_STATUS_NO_PROBLEMO;
 }
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name,
-                               const UNISTR2 *uni_environment,
-                               uint32 level,
-                               DRIVER_DIRECTORY_CTR *ctr,
-                               uint32 *offered)
+static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
+{
+       init_unistr(&(info->name), name);
+}
+
+/****************************************************************************
+****************************************************************************/
+static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        pstring chaine;
        pstring long_archi;
-       pstring archi;
-
+       pstring short_archi;
+       DRIVER_DIRECTORY_1 *info=NULL;
+       
+       info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1));
+       
        unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
-       get_short_archi(archi, long_archi);
+       get_short_archi(short_archi, long_archi);
                
-       slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\print$\\%s",
-                                        global_myname, archi);
+       slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
 
        DEBUG(4,("printer driver directory: [%s]\n", chaine));
-                                                           
-       init_unistr(&(ctr->driver.info_1.name), chaine);
 
-       return 0x0;
+       fill_driverdir_1(info, chaine);
+       
+       *needed += spoolss_size_driverdir_info_1(info);                                                     
+
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       new_smb_io_driverdir_1("", buffer, info, 0);
+
+       safe_free(info);
+       
+       if (*needed > offered)
+               return ERROR_INSUFFICIENT_BUFFER;
+       else
+               return NT_STATUS_NO_PROBLEMO;
 }
 
+/****************************************************************************
+****************************************************************************/
+uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
+                                       NEW_BUFFER *buffer, uint32 offered, 
+                                       uint32 *needed)
+{
+       DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
+
+       *needed=0;
+
+       switch(level) {
+       case 1:
+               return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
+               break;
+       default:
+               return NT_STATUS_INVALID_INFO_CLASS;
+               break;
+       }
+}
+       
 /****************************************************************************
 ****************************************************************************/
 uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, 
@@ -3755,84 +3893,127 @@ uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
 
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_getjob( const POLICY_HND *handle,
-                               uint32 jobid,
-                               uint32 level,
-                               PJOB_INFO *ctr,
-                               uint32 *offered)
+static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       int i=0;
+       BOOL found=False;
+       JOB_INFO_1 *info_1=NULL;
+       info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
+
+       if (info_1 == NULL) {
+               safe_free(queue);
+               return NT_STATUS_NO_MEMORY;
+       }
+               
+       for (i=0; i<count && found==False; i++) {
+               if (queue[i].job==(int)jobid)
+                       found=True;
+       }
+       
+       if (found==False) {
+               safe_free(queue);
+               /* I shoud reply something else ... I can't find the good one */
+               return NT_STATUS_NO_PROBLEMO;
+       }
+       
+       fill_job_info_1(info_1, &(queue[i]), i, snum);
+       
+       *needed += spoolss_size_job_info_1(info_1);
+
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       new_smb_io_job_info_1("", buffer, info_1, 0);
+
+       safe_free(info_1);
+
+       if (*needed > offered)
+               return ERROR_INSUFFICIENT_BUFFER;
+       else
+               return NT_STATUS_NO_PROBLEMO;
+}
+
+
+/****************************************************************************
+****************************************************************************/
+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;
+       BOOL found=False;
+       JOB_INFO_2 *info_2=NULL;
+       info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
+
+       if (info_2 == NULL) {
+               safe_free(queue);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0; i<count && found==False; i++) {
+               if (queue[i].job==(int)jobid)
+                       found=True;
+       }
+       
+       if (found==False) {
+               safe_free(queue);
+               /* I shoud reply something else ... I can't find the good one */
+               return NT_STATUS_NO_PROBLEMO;
+       }
+       
+       fill_job_info_2(info_2, &(queue[i]), i, snum);
+       
+       *needed += spoolss_size_job_info_2(info_2);
+
+       if (!alloc_buffer_size(buffer, *needed))
+               return ERROR_INSUFFICIENT_BUFFER;
+
+       new_smb_io_job_info_2("", buffer, info_2, 0);
+
+       safe_free(info_2);
+
+       if (*needed > offered)
+               return ERROR_INSUFFICIENT_BUFFER;
+       else
+               return NT_STATUS_NO_PROBLEMO;
+}
+
+/****************************************************************************
+****************************************************************************/
+uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
+                       NEW_BUFFER *buffer, uint32 offered, 
+                       uint32 *needed)
 {
        int snum;
        int count;
-       int i;
        print_queue_struct *queue=NULL;
        print_status_struct prt_status;
 
-       DEBUG(4,("spoolss_getjob\n"));
+       DEBUG(5,("spoolss_getjob\n"));
        
-       bzero(&prt_status,sizeof(prt_status));
+       bzero(&prt_status, sizeof(prt_status));
 
+       *needed=0;
+       
        if (!get_printer_snum(handle, &snum))
        {
                return NT_STATUS_INVALID_HANDLE;
        }
+       
        count=get_printqueue(snum, NULL, &queue, &prt_status);
        
        DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
                     count, prt_status.status, prt_status.message));
-       
-       switch (level)
-       {
-               case 1:
-               {
-                       JOB_INFO_1 *job_info_1=NULL;
-                       job_info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
-
-                       if (job_info_1 == NULL)
-                       {
-                               safe_free(queue);
-                               return NT_STATUS_NO_MEMORY;
-                       }
-
-                       for (i=0; i<count; i++)
-                       {
-                               if (queue[i].job==(int)jobid)
-                               {
-                                       fill_job_info_1(job_info_1,
-                                                      &(queue[i]), i, snum);
-                               }
-                       }
-                       ctr->job.job_info_1=job_info_1;
-                       break;
-               }
-               case 2:
-               {
-                       JOB_INFO_2 *job_info_2=NULL;
-                       job_info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
-
-                       if (job_info_2 == NULL)
-                       {
-                               safe_free(queue);
-                               return NT_STATUS_NO_MEMORY;
-                       }
-
-                       for (i=0; i<count; i++)
-                       {
-                               if (queue[i].job==(int)jobid)
-                               {
-                                       fill_job_info_2(job_info_2,
-                                                       &(queue[i]), i, snum);
-                               }
-                       }
-                       ctr->job.job_info_2=job_info_2;
-                       break;
-               }
-               default:
-               {
-                       safe_free(queue);
-                       return NT_STATUS_INVALID_INFO_CLASS;
-               }
+               
+       switch (level) {
+       case 1:
+               return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
+               break;
+       case 2:
+               return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
+               break;
+       default:
+               safe_free(queue);
+               return NT_STATUS_INVALID_INFO_CLASS;
+               break;
        }
-
-       safe_free(queue);
-       return 0x0;
 }
+