getprinter level 0: was to short, found most of the fields, undocumented,
authorJean-François Micouleau <jfm@samba.org>
Fri, 10 Mar 2000 17:12:24 +0000 (17:12 +0000)
committerJean-François Micouleau <jfm@samba.org>
Fri, 10 Mar 2000 17:12:24 +0000 (17:12 +0000)
undecoded, nothing in MSDN, but now it works :-)

cleanup of error codes.
fixed some dfs declarations function.

J.F.

source/include/nt_printing.h
source/include/nterr.h
source/include/proto.h
source/include/rpc_spoolss.h
source/include/smb.h
source/msdfs/msdfs_tdb.c
source/msdfs/parse_dfs_map.c
source/printing/nt_printing.c
source/rpc_parse/parse_spoolss.c
source/rpc_server/srv_spoolss_nt.c
source/smbd/ipc.c

index 99a427c32d3ca76511f9cbd8ed0039f71b9ddebd..7d4c4e9dd55a02ea343ac3fe7eacc47ea902573c 100644 (file)
@@ -1,3 +1,25 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB parameters and setup
+   Copyright (C) Andrew Tridgell              1992-2000,
+   Copyright (C) Jean Francois Micouleau      1998-2000.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
 #ifndef NT_PRINTING_H_
 #define NT_PRINTING_H_
 
@@ -195,7 +217,6 @@ typedef struct nt_printer_info_level_2
        fstring sharename;
        fstring portname;
        fstring drivername;
-       fstring comment;
        fstring location;
        NT_DEVICEMODE *devmode;
        fstring sepfile;
@@ -205,6 +226,9 @@ typedef struct nt_printer_info_level_2
        NT_PRINTER_PARAM *specific;
        /* SEC_DESC_BUF *secdesc; */
        /* not used but ... and how ??? */
+       uint32 changeid;
+       uint32 c_setprinter;
+       time_t setuptime;       
 } NT_PRINTER_INFO_LEVEL_2;
 
 typedef struct nt_printer_info_level
index df2cde61f70d9e494ec899d25e803fd6d1a9ae45..d2fe621b2905508eef6ec338751e075f8b152e17 100644 (file)
@@ -4,17 +4,6 @@
 #define STATUS_BUFFER_OVERFLOW            (5)
 #define STATUS_MORE_ENTRIES           (0x105)
 
-/* Win32 Error codes. */
-
-#define ERROR_ACCESS_DENIED              (5)
-#define ERROR_INVALID_HANDLE             (6)
-#define ERROR_INVALID_PARAMETER                 (87)
-#define ERROR_INSUFFICIENT_BUFFER      (122)
-#define ERROR_INVALID_NAME             (123)
-#define ERROR_NO_MORE_ITEMS            (259)
-#define ERROR_INVALID_PRINTER_NAME     (1801)
-#define ERROR_INVALID_DATATYPE        (1804)
-
 /* these are the NT error codes less than 1000. They are here for when
    we start supporting NT error codes in Samba. They were extracted
    using a loop in smbclient then printing a netmon sniff to a file */
index 20a459120f68abd572f1509b9d16998437eef0ca..6a09935226b7f036087ae89e72e57fdc4d7e213c 100644 (file)
@@ -820,15 +820,15 @@ BOOL msdfs_open(BOOL update);
 BOOL add_junction_entry(struct junction_map* junction);
 BOOL get_junction_entry(struct junction_map* junction);
 BOOL isDfsShare(char* svc,char* vol);
-void msdfs_close();
-void msdfs_end();
+void msdfs_close(void);
+void msdfs_end(void);
 
 /*The following definitions come from  msdfs/parse_dfs_map.c  */
 
 BOOL parse_referral(char* s, struct referral* ref);
-void load_dfsmaps();
+void load_dfsmaps(void);
 BOOL load_dfsmap(char* fname, int snum);
-void load_dfsmaps();
+void load_dfsmaps(void);
 
 /*The following definitions come from  nmbd/asyncdns.c  */
 
@@ -2338,7 +2338,7 @@ BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
 BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
                                      prs_struct *ps, int depth);
 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, 
-                                       uint32 access_required, fstring client_name, fstring user_name);
+                                       uint32 access_required, fstring clientname, fstring user_name);
 BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth);
 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
@@ -2458,7 +2458,7 @@ BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u,
 BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
 BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, POLICY_HND *hnd, uint32 index, uint32 valuelen, uint32 datalen);
+BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, POLICY_HND *hnd, uint32 idx, uint32 valuelen, uint32 datalen);
 BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
 BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
 BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
@@ -2704,11 +2704,11 @@ uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
 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 index,
+uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
                                uint32 in_value_len, uint32 in_data_len,
                                uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
                                uint32 *out_type,
-                               uint32 *out_max_data_len, uint8  **out_data, uint32 *out_data_len);
+                               uint32 *out_max_data_len, uint8  **data_out, uint32 *out_data_len);
 uint32 _spoolss_setprinterdata( const POLICY_HND *handle,
                                const UNISTR2 *value,
                                uint32 type,
index f9423245eb9f4662f0252ff0cbb584cb27f2e081..21fa9b5586ecf071869da505e25a41d8036b7bbe 100755 (executable)
@@ -712,35 +712,49 @@ typedef struct printer_info_0
        UNISTR printername;
        UNISTR servername;
        uint32 cjobs;
-       uint32 attributes;
-       uint32 unknown0;
-       uint32 unknown1;
-       uint32 unknown2;
-       uint32 unknown3;
-       uint32 unknown4;
-       uint32 unknown5;
-       uint32 unknown6;
-       uint16 majorversion;
-       uint16 buildversion;
+       uint32 total_jobs;
+       uint32 total_bytes;
+       
+       uint16 year;
+       uint16 month;
+       uint16 dayofweek;
+       uint16 day;
+       uint16 hour;
+       uint16 minute;
+       uint16 second;
+       uint16 milliseconds;
+
+       uint32 global_counter;
+       uint32 total_pages;
+
+       uint16 major_version;
+       uint16 build_version;
+
        uint32 unknown7;
        uint32 unknown8;
        uint32 unknown9;
-       uint32 unknown10;
+       uint32 session_counter;
        uint32 unknown11;
-       uint32 unknown12;
+       uint32 printer_errors;
        uint32 unknown13;
        uint32 unknown14;
        uint32 unknown15;
        uint32 unknown16;
-       uint32 unknown17;
+       uint32 change_id;
        uint32 unknown18;
        uint32 status;
        uint32 unknown20;
-       uint32 unknown21;
+       uint32 c_setprinter;
+
        uint16 unknown22;
-       uint32 unknown23;
-}
-PRINTER_INFO_0;
+       uint16 unknown23;
+       uint16 unknown24;
+       uint16 unknown25;
+       uint16 unknown26;
+       uint16 unknown27;
+       uint16 unknown28;
+       uint16 unknown29;
+} PRINTER_INFO_0;
 
 typedef struct printer_info_1
 {
@@ -830,11 +844,7 @@ typedef struct spool_r_getprinter
        NEW_BUFFER *buffer;
        uint32 needed;
        uint32 status;
-
-}
-SPOOL_R_GETPRINTER;
-
-struct _print_queue_struct;
+} SPOOL_R_GETPRINTER;
 
 struct s_notify_info_data_table
 {
@@ -842,16 +852,15 @@ struct s_notify_info_data_table
        uint16 field;
        char *name;
        uint32 size;
-       void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA * data,
-                   struct _print_queue_struct * queue,
-                   NT_PRINTER_INFO_LEVEL * printer);
+       void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
+                   print_queue_struct *queue,
+                   NT_PRINTER_INFO_LEVEL *printer);
 };
 
 typedef struct driver_info_1
 {
        UNISTR name;
-}
-DRIVER_INFO_1;
+} DRIVER_INFO_1;
 
 typedef struct driver_info_2
 {
@@ -861,8 +870,7 @@ typedef struct driver_info_2
        UNISTR driverpath;
        UNISTR datafile;
        UNISTR configfile;
-}
-DRIVER_INFO_2;
+} DRIVER_INFO_2;
 
 typedef struct driver_info_3
 {
index 447f2bd3a6b1a535364e9c0018b60963d11864b4..53454cc414266fa704e3478c60b790a5d2e2a24c 100644 (file)
@@ -169,11 +169,20 @@ implemented */
 #define ERRnotconnected 233 /* No process on other end of named pipe */
 #define ERRmoredata 234 /* More data to be returned */
 #define ERRbaddirectory 267 /* Invalid directory name in a path. */
-#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */
-#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */
-#define ERROR_NOTIFY_ENUM_DIR 1022 /* Buffer too small to return change notify. */
 #define ERRunknownipc 2142
 
+#define ERROR_ACCESS_DENIED              (5)
+#define ERROR_INVALID_HANDLE             (6)
+#define ERROR_INVALID_PARAMETER                 (87)
+#define ERROR_INSUFFICIENT_BUFFER      (122)
+#define ERROR_INVALID_NAME             (123)
+#define ERROR_INVALID_LEVEL            (124)
+#define ERROR_NO_MORE_ITEMS            (259)
+#define ERROR_EAS_DIDNT_FIT            (275) /* Extended attributes didn't fit */
+#define ERROR_EAS_NOT_SUPPORTED                (282) /* Extended attributes not supported */
+#define ERROR_NOTIFY_ENUM_DIR         (1022) /* Buffer too small to return change notify. */
+#define ERROR_INVALID_PRINTER_NAME     (1801)
+#define ERROR_INVALID_DATATYPE        (1804)
 
 /* here's a special one from observing NT */
 #define ERRnoipc 66 /* don't support ipc */
index 6f3b150c1e5b0b305421a5b33b0a0055ed8050ae..9ea5fe66417ce6137bd999cdae607f0e57769e63 100644 (file)
@@ -242,7 +242,7 @@ BOOL isDfsShare(char* svc,char* vol)
 
 }
 
-void msdfs_close()
+void msdfs_close(void)
 {
   if(msdfs_map != NULL)
       tdb_close(msdfs_map);
@@ -250,7 +250,7 @@ void msdfs_close()
   msdfs_map = NULL;
 }
 
-void msdfs_end()
+void msdfs_end(void)
 {
   pstring fname;
   msdfs_close();
index d7cc2b8725c1f3b0d3887d6d0c92e6c373c6a1b9..30bd010089f6cdbd17743b8dd6eb89e42367909d 100644 (file)
@@ -111,7 +111,7 @@ BOOL parse_referral(char* s, struct referral* ref)
   return True;
 }
 
-void load_dfsmaps()
+void load_dfsmaps(void)
 {
   int i=0;
   if(!lp_host_msdfs()) 
@@ -247,7 +247,7 @@ BOOL load_dfsmap(char* fname, int snum)
 #else 
 /* Stub function if MS_DFS is not defined */     
 
-void load_dfsmaps()
+void load_dfsmaps(void)
 {}       
          
 #endif         
index 061b41e123125037448abfc5614354ca18c9c538..a3320beccb0f6105ef79c1e988136ec84cad5b6d 100644 (file)
@@ -1,3 +1,25 @@
+/* 
+ *  Unix SMB/Netbios implementation.
+ *  Version 1.9.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell              1992-2000,
+ *  Copyright (C) Jean François Micouleau      1998-2000.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
 #include "includes.h"
 #include "nterr.h"
 
@@ -397,7 +419,7 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
                v=strncpyn(p, line, sizeof(p), ':');
                if (v==NULL)
                {
-                       DEBUG(1, ("malformed printer entry (no :)\n"));
+                       DEBUG(1, ("malformed printer driver entry (no :)\n"));
                        continue;
                }
                
@@ -444,7 +466,6 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
                        StrnCpy(dependentfiles[i], v, strlen(v) );
                        i++;
                }
-
        }
        
        free(line);
@@ -478,12 +499,8 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
                case 3: 
                {
                        if (driver.info_3 == NULL)
-                       {
-                               DEBUGADD(103,("NULL pointer, memory not alloced ?\n"));
                                success=5;
-                       }
-                       else
-                       {
+                       else {
                                info3=driver.info_3;
                        
                                DEBUGADD(106,("version:[%d]\n",         info3->cversion));
@@ -619,6 +636,9 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
        fprintf(f, "status: %d\n", info->status);
        fprintf(f, "cjobs: %d\n", info->cjobs);
        fprintf(f, "averageppm: %d\n", info->averageppm);
+       fprintf(f, "changeid: %d\n", info->changeid);
+       fprintf(f, "c_setprinter: %d\n", info->c_setprinter);
+       fprintf(f, "setuptime: %d\n", (int)info->setuptime);
 
        /* 
         * in addprinter: no servername and the printer is the name
@@ -641,7 +661,6 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
        fprintf(f, "sharename: %s\n", info->sharename);
        fprintf(f, "portname: %s\n", info->portname);
        fprintf(f, "drivername: %s\n", info->drivername);
-       fprintf(f, "comment: %s\n", info->comment);
        fprintf(f, "location: %s\n", info->location);
        fprintf(f, "sepfile: %s\n", info->sepfile);
        fprintf(f, "printprocessor: %s\n", info->printprocessor);
@@ -865,6 +884,15 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
                if (!strncmp(p, "averageppm", strlen("averageppm")))
                        info->averageppm=atoi(v);
                
+               if (!strncmp(p, "changeid", strlen("changeid")))
+                       info->changeid=atoi(v);
+               
+               if (!strncmp(p, "c_setprinter", strlen("c_setprinter")))
+                       info->c_setprinter=atoi(v);
+               
+               if (!strncmp(p, "setuptime", strlen("setuptime")))
+                       info->setuptime=atoi(v);
+               
                if (!strncmp(p, "servername", strlen("servername")))
                        StrnCpy(info->servername, v, strlen(v));
 
@@ -880,9 +908,6 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
                if (!strncmp(p, "drivername", strlen("drivername")))
                        StrnCpy(info->drivername, v, strlen(v));
 
-               if (!strncmp(p, "comment", strlen("comment")))
-                       StrnCpy(info->comment, v, strlen(v));
-
                if (!strncmp(p, "location", strlen("location")))
                        StrnCpy(info->location, v, strlen(v));
 
@@ -1015,34 +1040,33 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
                case 2: 
                {
                        if (printer.info_2 == NULL)
-                       {
-                               DEBUGADD(3,("NULL pointer, memory not alloced ?\n"));
                                success=5;
-                       }
                        else
                        {
                                info2=printer.info_2;
                        
-                               DEBUGADD(106,("attributes:[%d]\n",       info2->attributes));
-                               DEBUGADD(106,("priority:[%d]\n",         info2->priority));
+                               DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
+                               DEBUGADD(106,("priority:[%d]\n", info2->priority));
                                DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
-                               DEBUGADD(106,("starttime:[%d]\n",        info2->starttime));
-                               DEBUGADD(106,("untiltime:[%d]\n",        info2->untiltime));
-                               DEBUGADD(106,("status:[%d]\n",           info2->status));
-                               DEBUGADD(106,("cjobs:[%d]\n",            info2->cjobs));
-                               DEBUGADD(106,("averageppm:[%d]\n",       info2->averageppm));
-
-                               DEBUGADD(106,("servername:[%s]\n",       info2->servername));
-                               DEBUGADD(106,("printername:[%s]\n",      info2->printername));
-                               DEBUGADD(106,("sharename:[%s]\n",        info2->sharename));
-                               DEBUGADD(106,("portname:[%s]\n",         info2->portname));
-                               DEBUGADD(106,("drivername:[%s]\n",       info2->drivername));
-                               DEBUGADD(106,("comment:[%s]\n",          info2->comment));
-                               DEBUGADD(106,("location:[%s]\n",         info2->location));
-                               DEBUGADD(106,("sepfile:[%s]\n",          info2->sepfile));
-                               DEBUGADD(106,("printprocessor:[%s]\n",   info2->printprocessor));
-                               DEBUGADD(106,("datatype:[%s]\n",         info2->datatype));
-                               DEBUGADD(106,("parameters:[%s]\n",       info2->parameters));
+                               DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
+                               DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
+                               DEBUGADD(106,("status:[%d]\n", info2->status));
+                               DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
+                               DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
+                               DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
+                               DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
+                               DEBUGADD(106,("setuptime:[%d]\n", (int)info2->setuptime));
+
+                               DEBUGADD(106,("servername:[%s]\n", info2->servername));
+                               DEBUGADD(106,("printername:[%s]\n", info2->printername));
+                               DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
+                               DEBUGADD(106,("portname:[%s]\n", info2->portname));
+                               DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
+                               DEBUGADD(106,("location:[%s]\n", info2->location));
+                               DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
+                               DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
+                               DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
+                               DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
                                success=0;
                        }
                        break;
index d9e761da6138b725399ab90246d3e835f363708f..902cc058c3b5fa3df6ca0712338ec1d60752ea1f 100644 (file)
@@ -633,7 +633,7 @@ static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_stru
  * init a structure.
  ********************************************************************/
 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, 
-                                       uint32 access_required, fstring client_name, fstring user_name)
+                                       uint32 access_required, fstring clientname, fstring user_name)
 {
        DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
        q_u->printername_ptr = (printername!=NULL)?1:0;
@@ -651,14 +651,14 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printe
        q_u->user_switch=1;
        q_u->user_ctr.level=1;
        q_u->user_ctr.ptr=1;
-       q_u->user_ctr.user1.size=strlen(client_name)+strlen(user_name)+8;
-       q_u->user_ctr.user1.client_name_ptr = (client_name!=NULL)?1:0;
+       q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+8;
+       q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
        q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
        q_u->user_ctr.user1.build=1381;
        q_u->user_ctr.user1.major=2;
        q_u->user_ctr.user1.minor=0;
        q_u->user_ctr.user1.processor=0;
-       init_unistr2(&(q_u->user_ctr.user1.client_name), client_name, strlen(client_name));
+       init_unistr2(&(q_u->user_ctr.user1.client_name), clientname, strlen(clientname));
        init_unistr2(&(q_u->user_ctr.user1.user_name), user_name, strlen(user_name));
        
        return True;
@@ -1144,6 +1144,14 @@ BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, in
        return True;
 }
 
+/*******************************************************************
+ * return the length of a uint16 (obvious, but the code is clean)
+ ********************************************************************/
+static uint32 size_of_uint16(uint16 *value)
+{
+       return (sizeof(*value));
+}
+
 /*******************************************************************
  * return the length of a uint32 (obvious, but the code is clean)
  ********************************************************************/
@@ -1151,7 +1159,6 @@ static uint32 size_of_uint32(uint32 *value)
 {
        return (sizeof(*value));
 }
-
 /*******************************************************************
  * return the length of a UNICODE string in number of char, includes:
  * - the leading zero
@@ -1405,26 +1412,36 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
        
        if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
                return False;
-       if(!prs_uint32("attributes", ps, depth, &info->attributes))
+       if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
+               return False;
+       if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
                return False;
 
-       if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
+       if(!prs_uint16("year", ps, depth, &info->year))
+               return False;
+       if(!prs_uint16("month", ps, depth, &info->month))
                return False;
-       if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
+       if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
                return False;
-       if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
+       if(!prs_uint16("day", ps, depth, &info->day))
                return False;
-       if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
+       if(!prs_uint16("hour", ps, depth, &info->hour))
                return False;
-       if(!prs_uint32("unknown4", ps, depth, &info->unknown4))
+       if(!prs_uint16("minute", ps, depth, &info->minute))
                return False;
-       if(!prs_uint32("unknown5", ps, depth, &info->unknown5))
+       if(!prs_uint16("second", ps, depth, &info->second))
                return False;
-       if(!prs_uint32("unknown6", ps, depth, &info->unknown6))
+       if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
                return False;
-       if(!prs_uint16("majorversion", ps, depth, &info->majorversion))
+
+       if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
                return False;
-       if(!prs_uint16("buildversion", ps, depth, &info->buildversion))
+       if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
+               return False;
+
+       if(!prs_uint16("major_version", ps, depth, &info->major_version))
+               return False;
+       if(!prs_uint16("build_version", ps, depth, &info->build_version))
                return False;
        if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
                return False;
@@ -1432,11 +1449,11 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
                return False;
        if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
                return False;
-       if(!prs_uint32("unknown10", ps, depth, &info->unknown10))
+       if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
                return False;
        if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
                return False;
-       if(!prs_uint32("unknown12", ps, depth, &info->unknown12))
+       if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
                return False;
        if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
                return False;
@@ -1446,7 +1463,7 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
                return False;
        if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
                return False;
-       if(!prs_uint32("unknown17", ps, depth, &info->unknown17))
+       if(!prs_uint32("change_id", ps, depth, &info->change_id))
                return False;
        if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
                return False;
@@ -1454,11 +1471,23 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i
                return False;
        if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
                return False;
-       if(!prs_uint32("unknown21", ps, depth, &info->unknown21))
+       if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
                return False;
        if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
                return False;
-       if(!prs_uint32("unknown23", ps, depth, &info->unknown23))
+       if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
+               return False;
+       if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
+               return False;
+       if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
+               return False;
+       if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
+               return False;
+       if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
+               return False;
+       if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
+               return False;
+       if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
                return False;
 
        return True;
@@ -2034,13 +2063,53 @@ uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
 {
        int size=0;
        
-       size+=24*4;
-       size+=6;
+       size+=size_of_relative_string( &info->printername );
+       size+=size_of_relative_string( &info->servername );
+
+       size+=size_of_uint32( &info->cjobs);
+       size+=size_of_uint32( &info->total_jobs);
+       size+=size_of_uint32( &info->total_bytes);
+
+       size+=size_of_uint16( &info->year);
+       size+=size_of_uint16( &info->month);
+       size+=size_of_uint16( &info->dayofweek);
+       size+=size_of_uint16( &info->day);
+       size+=size_of_uint16( &info->hour);
+       size+=size_of_uint16( &info->minute);
+       size+=size_of_uint16( &info->second);
+       size+=size_of_uint16( &info->milliseconds);
+
+       size+=size_of_uint32( &info->global_counter);
+       size+=size_of_uint32( &info->total_pages);
+
+       size+=size_of_uint16( &info->major_version);
+       size+=size_of_uint16( &info->build_version);
+
+       size+=size_of_uint32( &info->unknown7);
+       size+=size_of_uint32( &info->unknown8);
+       size+=size_of_uint32( &info->unknown9);
+       size+=size_of_uint32( &info->session_counter);
+       size+=size_of_uint32( &info->unknown11);
+       size+=size_of_uint32( &info->printer_errors);
+       size+=size_of_uint32( &info->unknown13);
+       size+=size_of_uint32( &info->unknown14);
+       size+=size_of_uint32( &info->unknown15);
+       size+=size_of_uint32( &info->unknown16);
+       size+=size_of_uint32( &info->change_id);
+       size+=size_of_uint32( &info->unknown18);
+       size+=size_of_uint32( &info->status);
+       size+=size_of_uint32( &info->unknown20);
+       size+=size_of_uint32( &info->c_setprinter);
+       
+       size+=size_of_uint16( &info->unknown22);
+       size+=size_of_uint16( &info->unknown23);
+       size+=size_of_uint16( &info->unknown24);
+       size+=size_of_uint16( &info->unknown25);
+       size+=size_of_uint16( &info->unknown26);
+       size+=size_of_uint16( &info->unknown27);
+       size+=size_of_uint16( &info->unknown28);
+       size+=size_of_uint16( &info->unknown29);
        
-       size+=size_of_uint32( &(info->attributes) );    
-       size+=size_of_relative_string( &(info->printername) );
-       size+=size_of_relative_string( &(info->servername) );
-
        return size;
 }
 
@@ -3432,8 +3501,11 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
                               NT_PRINTER_INFO_LEVEL_2  **asc)
 {
        NT_PRINTER_INFO_LEVEL_2 *d;
+       NTTIME time_nt;
+       time_t time_unix;
        
        DEBUG(7,("Converting from UNICODE to ASCII\n"));
+       time_unix=time(NULL);
        
        if (*asc==NULL)
        {
@@ -3441,6 +3513,12 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
 
                *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
                ZERO_STRUCTP(*asc);
+               
+               /* we allocate memory iff called from 
+                * addprinter(ex) so we can do one time stuff here.
+                */
+               (*asc)->setuptime=time_unix;
+
        }       
        DEBUGADD(8,("start converting\n"));
 
@@ -3454,17 +3532,21 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
        d->status=uni->status;
        d->cjobs=uni->cjobs;
 
-       unistr2_to_ascii(d->servername,     &(uni->servername),     sizeof(d->servername)-1);
-       unistr2_to_ascii(d->printername,    &(uni->printername),    sizeof(d->printername)-1);
-       unistr2_to_ascii(d->sharename,      &(uni->sharename),      sizeof(d->sharename)-1);
-       unistr2_to_ascii(d->portname,       &(uni->portname),       sizeof(d->portname)-1);
-       unistr2_to_ascii(d->drivername,     &(uni->drivername),     sizeof(d->drivername)-1);
-       unistr2_to_ascii(d->comment,        &(uni->comment),        sizeof(d->comment)-1);
-       unistr2_to_ascii(d->location,       &(uni->location),       sizeof(d->location)-1);
-       unistr2_to_ascii(d->sepfile,        &(uni->sepfile),        sizeof(d->sepfile)-1);
-       unistr2_to_ascii(d->printprocessor, &(uni->printprocessor), sizeof(d->printprocessor)-1);
-       unistr2_to_ascii(d->datatype,       &(uni->datatype),       sizeof(d->datatype)-1);
-       unistr2_to_ascii(d->parameters,     &(uni->parameters),     sizeof(d->parameters)-1);
+       unix_to_nt_time(&time_nt, time_unix);
+       d->changeid=time_nt.low;
+       
+       d->c_setprinter++;
+
+       unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
+       unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
+       unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
+       unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
+       unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
+       unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
+       unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
+       unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
+       unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
+       unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
 
        return True;
 }
@@ -3790,10 +3872,10 @@ BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_
 
 /*******************************************************************
 ********************************************************************/  
-BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, POLICY_HND *hnd, uint32 index, uint32 valuelen, uint32 datalen)
+BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, POLICY_HND *hnd, uint32 idx, uint32 valuelen, uint32 datalen)
 {
        memcpy(&(q_u->handle), hnd, sizeof(q_u->handle));
-       q_u->index=index;
+       q_u->index=idx;
        q_u->valuesize=valuelen;
        q_u->datasize=datalen;
 
index 41f37c3f74a30ffd96a4a0a2e9b4413e7908492e..9170b8afdd9e536d449dafe6b35c935126919cb7 100644 (file)
@@ -72,7 +72,17 @@ typedef struct _Printer{
        } client;
 } Printer_entry;
 
+typedef struct _counter_printer_0 {
+       ubi_dlNode Next;
+       ubi_dlNode Prev;
+       
+       int snum;
+       uint32 counter;
+} counter_printer_0;
+
 static ubi_dlList Printer_list;
+static ubi_dlList counter_list;
+
 
 #define OPEN_HANDLE(pnum)    ((pnum!=NULL) && (pnum->open!=False))
 
@@ -82,6 +92,7 @@ static ubi_dlList Printer_list;
 void init_printer_hnd(void)
 {
        ubi_dlInitList(&Printer_list);
+       ubi_dlInitList(&counter_list);
 }
 
 /****************************************************************************
@@ -1485,22 +1496,50 @@ uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change,
  * construct_printer_info_0
  * fill a printer_info_1 struct
  ********************************************************************/
-static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring servername)
+static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, pstring servername)
 {
        pstring chaine;
        int count;
        NT_PRINTER_INFO_LEVEL ntprinter;
-       
+       counter_printer_0 *session_counter;
+       uint32 global_counter;
+       struct tm *t;
+
        print_queue_struct *queue=NULL;
        print_status_struct status;
+       
        memset(&status, 0, sizeof(status));     
 
        if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
-       {
-               return (False);
-       }
+               return False;
 
        count=get_printqueue(snum, NULL, &queue, &status);
+
+       /* check if we already have a counter for this printer */       
+       session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
+
+       for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
+               if (session_counter->snum == snum)
+                       break;
+       }
+
+       /* it's the first time, add it to the list */
+       if (session_counter==NULL) {
+               session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0));
+               ZERO_STRUCTP(session_counter);
+               session_counter->snum=snum;
+               session_counter->counter=0;
+               ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
+       }
+       
+       /* increment it */
+       session_counter->counter++;
+       
+       /* JFM:
+        * the global_counter should be stored in a TDB as it's common to all the clients
+        * and should be zeroed on samba startup
+        */
+       global_counter=session_counter->counter;
        
        /* the description and the name are of the form \\server\share */
        slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter.info_2->printername);
@@ -1511,36 +1550,48 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
        init_unistr(&(printer->servername), chaine);
        
        printer->cjobs = count;
-       printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
-                             | PRINTER_ATTRIBUTE_NETWORK  \
-                             | PRINTER_ATTRIBUTE_RAW_ONLY ;
-       printer->unknown0     = 0x1; /* pointer */
-       printer->unknown1     = 0x000A07CE; /* don't known */
-       printer->unknown2     = 0x00020005;
-       printer->unknown3     = 0x0006000D;
-       printer->unknown4     = 0x02180026;
-       printer->unknown5     = 0x09;
-       printer->unknown6     = 0x36;
-       printer->majorversion = 0x0004; /* NT 4 */
-       printer->buildversion = 0x0565; /* build 1381 */
-       printer->unknown7     = 0x1;
-       printer->unknown8     = 0x0;
-       printer->unknown9     = 0x2;
-       printer->unknown10    = 0x3;
-       printer->unknown11    = 0x0;
-       printer->unknown12    = 0x0;
-       printer->unknown13    = 0x0;
-       printer->unknown14    = 0x1;
-       printer->unknown15    = 0x024a; /*586 Pentium ? */
-       printer->unknown16    = 0x0;
-       printer->unknown17    = 0x423ed444; /* CacheChangeID */
-       printer->unknown18    = 0x0;
-       printer->status       = status.status;
-       printer->unknown20    = 0x0;
-       printer->unknown21    = 0x0648;
-       printer->unknown22    = 0x0;
-       printer->unknown23    = 0x5;
-
+       printer->total_jobs = 0;
+       printer->total_bytes = 0;
+
+       t=gmtime(&ntprinter.info_2->setuptime);
+
+       printer->year = t->tm_year+1900;
+       printer->month = t->tm_mon+1;
+       printer->dayofweek = t->tm_wday;
+       printer->day = t->tm_mday;
+       printer->hour = t->tm_hour;
+       printer->minute = t->tm_min;
+       printer->second = t->tm_sec;
+       printer->milliseconds = 0;
+
+       printer->global_counter = global_counter;
+       printer->total_pages = 0;
+       printer->major_version = 0x0004;        /* NT 4 */
+       printer->build_version = 0x0565;        /* build 1381 */
+       printer->unknown7 = 0x1;
+       printer->unknown8 = 0x0;
+       printer->unknown9 = 0x2;
+       printer->session_counter = session_counter->counter;
+       printer->unknown11 = 0x0;
+       printer->printer_errors = 0x0;          /* number of print failure */
+       printer->unknown13 = 0x0;
+       printer->unknown14 = 0x1;
+       printer->unknown15 = 0x024a;            /* 586 Pentium ? */
+       printer->unknown16 = 0x0;
+       printer->change_id = ntprinter.info_2->changeid; /* ChangeID in milliseconds*/
+       printer->unknown18 = 0x0;
+       printer->status = status.status;
+       printer->unknown20 = 0x0;
+       printer->c_setprinter = ntprinter.info_2->c_setprinter; /* how many times setprinter has been called */
+       printer->unknown22 = 0x0;
+       printer->unknown23 = 0x6;               /* 6  ???*/
+       printer->unknown24 = 0;                 /* unknown 24 to 26 are always 0 */
+       printer->unknown25 = 0;
+       printer->unknown26 = 0;
+       printer->unknown27 = 0;
+       printer->unknown28 = 0;
+       printer->unknown29 = 0;
+       
        safe_free(queue);
 
        free_a_printer(ntprinter, 2);
@@ -1640,52 +1691,57 @@ static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername)
  * construct_printer_info_2
  * fill a printer_info_2 struct
  ********************************************************************/
-static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring servername)
+static BOOL construct_printer_info_2(pstring servername, PRINTER_INFO_2 *printer, int snum)
 {
        pstring chaine;
+       pstring chaine2;
+       pstring sl;
        int count;
        DEVICEMODE *devmode;
        NT_PRINTER_INFO_LEVEL ntprinter;
-       
+
        print_queue_struct *queue=NULL;
        print_status_struct status;
        memset(&status, 0, sizeof(status));     
-       count=get_printqueue(snum, NULL, &queue, &status);
 
        if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
-       {
-               return (False);
-       }       
-
-       snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername);
-       init_unistr(&(printer->servername), chaine);                    /* servername*/
-       
-       snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername);
-       init_unistr(&(printer->printername), chaine);                   /* printername*/
+               return False;
+               
+       memset(&status, 0, sizeof(status));             
+       count=get_printqueue(snum, NULL, &queue, &status);
 
-       init_unistr(&(printer->sharename),      lp_servicename(snum));  /* sharename */
+       snprintf(chaine, sizeof(chaine)-1, "%s", servername);
 
-       init_unistr(&(printer->portname),       lp_servicename(snum));          /* port */      
-       init_unistr(&(printer->drivername),     ntprinter.info_2->drivername);  /* drivername */
-               
-       init_unistr(&(printer->comment),        ntprinter.info_2->comment);     /* comment */   
-       init_unistr(&(printer->location),       ntprinter.info_2->location);    /* location */  
-       init_unistr(&(printer->sepfile),        ntprinter.info_2->sepfile);     /* separator file */
-       init_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */
-       init_unistr(&(printer->datatype),       ntprinter.info_2->datatype);    /* datatype */  
-       init_unistr(&(printer->parameters),     ntprinter.info_2->parameters);  /* parameters (of print processor) */   
+       if (strlen(servername)!=0)
+               fstrcpy(sl, "\\");
+       else
+               fstrcpy(sl, '\0');
+
+       snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter.info_2->printername);
+
+       init_unistr(&printer->servername, chaine);                              /* servername*/
+       init_unistr(&printer->printername, chaine2);                            /* printername*/
+       init_unistr(&printer->sharename, lp_servicename(snum));                 /* sharename */
+       init_unistr(&printer->portname, lp_servicename(snum));                  /* port */      
+       init_unistr(&printer->drivername, ntprinter.info_2->drivername);        /* drivername */
+       init_unistr(&printer->comment, lp_comment(snum));                       /* comment */   
+       init_unistr(&printer->location, ntprinter.info_2->location);            /* location */  
+       init_unistr(&printer->sepfile, ntprinter.info_2->sepfile);              /* separator file */
+       init_unistr(&printer->printprocessor, ntprinter.info_2->printprocessor);/* print processor */
+       init_unistr(&printer->datatype, ntprinter.info_2->datatype);            /* datatype */  
+       init_unistr(&printer->parameters, ntprinter.info_2->parameters);        /* parameters (of print processor) */   
 
        printer->attributes =   PRINTER_ATTRIBUTE_SHARED   \
-                             | PRINTER_ATTRIBUTE_NETWORK  \
-                             | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
-
-       printer->priority        = ntprinter.info_2->priority;          /* priority */  
-       printer->defaultpriority = ntprinter.info_2->default_priority;  /* default priority */
-       printer->starttime       = ntprinter.info_2->starttime;         /* starttime */
-       printer->untiltime       = ntprinter.info_2->untiltime;         /* untiltime */
-       printer->status          = status.status;                       /* status */
-       printer->cjobs           = count;                               /* jobs */
-       printer->averageppm      = ntprinter.info_2->averageppm;        /* average pages per minute */
+                             | PRINTER_ATTRIBUTE_LOCAL  \
+                             | PRINTER_ATTRIBUTE_RAW_ONLY ;                    /* attributes */
+
+       printer->priority = ntprinter.info_2->priority;                         /* priority */  
+       printer->defaultpriority = ntprinter.info_2->default_priority;          /* default priority */
+       printer->starttime = ntprinter.info_2->starttime;                       /* starttime */
+       printer->untiltime = ntprinter.info_2->untiltime;                       /* untiltime */
+       printer->status = status.status;                                        /* status */
+       printer->cjobs = count;                                                 /* jobs */
+       printer->averageppm = ntprinter.info_2->averageppm;                     /* average pages per minute */
                        
        devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
        ZERO_STRUCTP(devmode);  
@@ -1694,29 +1750,7 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring
        
        safe_free(queue);
        free_a_printer(ntprinter, 2);
-       return (True);
-}
-
-/********************************************************************
- * enum_printer_info_2
- * glue between spoolss_enumprinters and construct_printer_info_2
- ********************************************************************/
-static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number)
-{
-       pstring servername;
-
-       *printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));
-       DEBUG(4,("Allocated memory for ONE PRINTER_INFO_2 at [%p]\n", *printer));       
-       pstrcpy(servername, global_myname);
-       if (!construct_printer_info_2(*printer, snum, servername))
-       {
-               free(*printer);
-               return (False);
-       }
-       else
-       {
-               return (True);
-       }
+       return True;
 }
 
 /********************************************************************
@@ -1736,8 +1770,7 @@ static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *b
                if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
                        DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
                                
-                       if (construct_printer_info_1(server, flags, &current_prt, snum))
-                       {
+                       if (construct_printer_info_1(server, flags, &current_prt, snum)) {
                                printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1));
                                DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));             
                                memcpy(&(printers[*returned]), &current_prt, sizeof(PRINTER_INFO_1));
@@ -1781,10 +1814,10 @@ static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uin
 
        if (!strcmp(name, temp)) {
                fstrcat(temp, "\\");
-               enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+               return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
        }
        else
-               enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+               return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
 }
 
 /********************************************************************
@@ -1800,7 +1833,7 @@ static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint
 
        if (!strcmp(name, temp)) {
                fstrcat(temp, "\\");
-               enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+               return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
        }
        else
                return ERROR_INVALID_NAME;
@@ -1840,8 +1873,10 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_1("", buffer, printer, 0);      
@@ -1868,7 +1903,7 @@ static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, u
        fstrcpy(temp, "\\\\");
        fstrcat(temp, global_myname);
        fstrcat(temp, "\\");
-       enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
+       return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
 }
 
 /********************************************************************
@@ -1876,38 +1911,40 @@ static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, u
  *
  * called from api_spoolss_enumprinters (see this to understand)
  ********************************************************************/
-static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
-       PRINTER_INFO_2 **printers=NULL;
+       PRINTER_INFO_2 *printers=NULL;
+       PRINTER_INFO_2 current_prt;
 
        for (snum=0; snum<n_services; snum++) {
                if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
-               
                        DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-                       printers=Realloc(printers, ((*returned)+1)*sizeof(PRINTER_INFO_2 *));
-                       DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2 pointers\n", (*returned)+1));                        
-                       if (get_printer_info_2( &(printers[*returned]), snum, *returned) )
+                               
+                       if (construct_printer_info_2(servername, &current_prt, snum)) {
+                               printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2));
+                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));             
+                               memcpy(&(printers[*returned]), &current_prt, sizeof(PRINTER_INFO_2));
                                (*returned)++;
+                       }
                }
        }
        
        /* check the required size. */  
        for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_2(printers[i]);
-
-       DEBUG(4,("we need [%d] bytes\n", *needed));
+               (*needed) += spoolss_size_printer_info_2(&(printers[i]));
 
        if (!alloc_buffer_size(buffer, *needed))
                return ERROR_INSUFFICIENT_BUFFER;
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
-               new_smb_io_printer_info_2("", buffer, printers[i], 0);  
+               new_smb_io_printer_info_2("", buffer, &(printers[i]), 0);       
        
        /* clear memory */
+       safe_free(printers);
 
        if (*needed > offered) {
                *returned=0;
@@ -1948,7 +1985,33 @@ static uint32 enumprinters_level2( uint32 flags, fstring servername,
                                 NEW_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
-       return enum_all_printers_info_2(buffer, offered, needed, returned);
+       fstring temp;
+       
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, global_myname);
+
+       if (flags & PRINTER_ENUM_LOCAL) {
+               if (!strcmp(servername, temp)) {
+                       fstrcat(temp, "\\");
+                       return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
+               }
+               else
+                       return enum_all_printers_info_2("", buffer, offered, needed, returned);
+       }
+
+       if (flags & PRINTER_ENUM_NAME) {
+               if (!strcmp(servername, temp)) {
+                       fstrcat(temp, "\\");
+                       return enum_all_printers_info_2(temp, buffer, offered, needed, returned);
+               }
+               else
+                       return ERROR_INVALID_NAME;
+       }
+
+       if (flags & PRINTER_ENUM_REMOTE)
+               return ERROR_INVALID_LEVEL;
+
+       return NT_STATUS_NO_PROBLEMO;
 }
 
 /********************************************************************
@@ -2018,13 +2081,16 @@ static uint32 getprinter_level_0(pstring servername, int snum, NEW_BUFFER *buffe
        PRINTER_INFO_0 *printer=NULL;
 
        printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0));
+
        construct_printer_info_0(printer, snum, servername);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_0(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_0("", buffer, printer, 0);      
@@ -2051,8 +2117,10 @@ static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffe
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_1("", buffer, printer, 0);      
@@ -2072,15 +2140,21 @@ static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffe
 static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_2 *printer=NULL;
+       fstring temp;
 
-       printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));        
-       construct_printer_info_2(printer, snum, servername);
+       printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));
+       
+       fstrcpy(temp, "\\\\");
+       fstrcat(temp, servername);
+       construct_printer_info_2(temp, printer, snum);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_2(printer);
 
-       if (!alloc_buffer_size(buffer, *needed))
+       if (!alloc_buffer_size(buffer, *needed)) {
+               safe_free(printer);
                return ERROR_INSUFFICIENT_BUFFER;
+       }
 
        /* fill the buffer with the structures */
        new_smb_io_printer_info_2("", buffer, printer, 0);      
@@ -2108,9 +2182,7 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
        pstrcpy(servername, global_myname);
 
        if (!get_printer_snum(handle, &snum))
-       {
                return NT_STATUS_INVALID_HANDLE;
-       }
 
        switch (level) {
        case 0:
@@ -2123,7 +2195,7 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
                return getprinter_level_2(servername,snum, buffer, offered, needed);
                break;
        default:
-               return NT_STATUS_INVALID_LEVEL;
+               return ERROR_INVALID_LEVEL;
                break;
        }
 }      
@@ -3617,11 +3689,11 @@ uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environmen
        
 /****************************************************************************
 ****************************************************************************/
-uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
+uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx,
                                uint32 in_value_len, uint32 in_data_len,
                                uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
                                uint32 *out_type,
-                               uint32 *out_max_data_len, uint8  **out_data, uint32 *out_data_len)
+                               uint32 *out_max_data_len, uint8  **data_out, uint32 *out_data_len)
 {
        NT_PRINTER_INFO_LEVEL printer;
        
@@ -3645,7 +3717,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
        *out_type=0;
 
        *out_max_data_len=0;
-       *out_data=NULL;
+       *data_out=NULL;
        *out_data_len=0;
 
        DEBUG(5,("spoolss_enumprinterdata\n"));
@@ -3696,7 +3768,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
         * that's the number of bytes not the number of unicode chars
         */
  
-       if (!get_specific_param_by_index(printer, 2, index, value, &data, &type, &data_len)) {
+       if (!get_specific_param_by_index(printer, 2, idx, value, &data, &type, &data_len)) {
                free_a_printer(printer, 2);
                return ERROR_NO_MORE_ITEMS;
        }
@@ -3719,7 +3791,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
 
        /* the data is counted in bytes */
        *out_max_data_len=in_data_len;
-       *out_data=(uint8 *)malloc(in_data_len*sizeof(uint8));
+       *data_out=(uint8 *)malloc(in_data_len*sizeof(uint8));
        memcpy(*out_data, data, data_len);
        *out_data_len=data_len;
 
index d42c2727d4fc9498241f74c09d3062db73d128fc..fc05811ccfe03e9ede783897978144fdea06f44b 100644 (file)
@@ -48,7 +48,6 @@ extern fstring global_myworkgroup;
 #define NERR_BufTooSmall (NERR_BASE+23)
 #define NERR_JobNotFound (NERR_BASE+51)
 #define NERR_DestNotFound (NERR_BASE+52)
-#define ERROR_INVALID_LEVEL 124
 
 #define ACCESS_READ 0x01
 #define ACCESS_WRITE 0x02