printing merge from SAMBA_2_2. Ther server code looks to be in sync now.
authorGerald Carter <jerry@samba.org>
Mon, 24 Jun 2002 19:51:23 +0000 (19:51 +0000)
committerGerald Carter <jerry@samba.org>
Mon, 24 Jun 2002 19:51:23 +0000 (19:51 +0000)
Mostly formatting and s/free/SAFE_FREE/g changes with the two exceptions
being

  * John driver init changes
  * Tim's printer enumeration bug fix

source/printing/nt_printing.c
source/printing/pcap.c
source/printing/print_cups.c
source/printing/printing.c
source/rpc_parse/parse_spoolss.c
source/rpc_server/srv_spoolss_nt.c

index ecf873c1ba4cedde1fdbac601d0252eed3bc4738..08d5ea430a512b5f5cf1296aeba5cf3ae086caa3 100644 (file)
@@ -2838,7 +2838,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
  Initialize printer devmode & data with previously saved driver init values.
 ****************************************************************************/
 
-static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
+static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
 {
        int                     len = 0;
        pstring                 key;
@@ -2891,9 +2891,14 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
         * NT/2k does not change out the entire DeviceMode of a printer
         * when changing the driver.  Only the driverextra, private, & 
         * driverversion fields.   --jerry  (Thu Mar 14 08:58:43 CST 2002)
+        *
+        * Later e4xamination revealed that Windows NT/2k does reset the
+        * the printer's device mode, bit **only** when you change a 
+        * property of the device mode such as the page orientation.
+        * --jerry
         */
 
-#if 0  /* JERRY */
+#if 1  /* JERRY */
 
        /* 
         *      Bind the saved DEVMODE to the new the printer.
@@ -2945,19 +2950,19 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
  is bound to the new printer.
 ****************************************************************************/
 
-uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
+BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
-       uint32 result;
+       BOOL result = False;
        
        switch (level)
        {
                case 2:
-               {
                        result=set_driver_init_2(printer->info_2);
                        break;
-               }
+                       
                default:
-                       result=1;
+                       DEBUG(0,("set_driver_init: Programmer's error!  Unknown driver_init level [%d]\n",
+                               level));
                        break;
        }
        
index 920c6f354e27daa0ba0f4ac2c012dc880eb6d428..01e03c7c6becdd9a19840bf2656f6b145d72d81a 100644 (file)
@@ -111,7 +111,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
 
        iEtat = 0;
        /* scan qconfig file for searching <printername>:       */
-       for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+       for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
        {
                if (*line == '*' || *line == 0)
                continue;
@@ -181,7 +181,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
        if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
        {
              DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
-             free(pName);
+             SAFE_FREE(pName);
              return(False);
        }
        slprintf(pName, iLg + 9, "%s:",pszPrintername);
@@ -189,7 +189,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
        /*DEBUG(3,( " Looking for entry %s\n",pName));*/
        iEtat = 0;
        /* scan qconfig file for searching <printername>:       */
-       for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+       for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
        {
                if (*line == '*' || *line == 0)
                continue;
@@ -208,8 +208,8 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
                         {
                           /* name is found without stanza device  */
                           /* probably a good printer ???               */
-                          free (line);
-                          free(pName);
+                          SAFE_FREE (line);
+                          SAFE_FREE(pName);
                           fclose(pfile);
                           return(True);
                          }
@@ -222,15 +222,15 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
                          else if (strlocate(line,"device"))
                          {
                                /* it's a good virtual printer */
-                               free (line);
-                               free(pName);
+                               SAFE_FREE (line);
+                               SAFE_FREE(pName);
                                fclose(pfile);
                                return(True);
                          }
                          break;
                }
        }
-       free (pName);
+       SAFE_FREE (pName);
        x_fclose(pfile);
        return(False);
 }
@@ -288,7 +288,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
       return(False);
     }
 
-  for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+  for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
     {
       if (*line == '#' || *line == 0)
        continue;
@@ -307,7 +307,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
            {
              /* normalise the case */
              pstrcpy(pszPrintername,p);
-             free(line);
+             SAFE_FREE(line);
              x_fclose(pfile);
              return(True);           
            }
@@ -369,7 +369,7 @@ void pcap_printer_fn(void (*fn)(char *, char *))
       return;
     }
 
-  for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+  for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
     {
       if (*line == '#' || *line == 0)
        continue;
index b5315e10b2867d37cf068bd253a72cc590e276a0..51ebb739a33afda78ff8b3cf4f316e037e65c700 100644 (file)
@@ -824,7 +824,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
                                ippDelete(response);
                                httpClose(http);
 
-                               free (queue);
+                               SAFE_FREE(queue);
                                return (0);
                        }
 
index 47fc019d645f154ca8e52646b448b6f5df59fe63..aa9df5e47fffcff3306b66ddbfd331ec2c2ef16e 100644 (file)
@@ -52,7 +52,8 @@ BOOL print_backend_init(void)
 {
        char *sversion = "INFO/version";
 
-       if (tdb && local_pid == sys_getpid()) return True;
+       if (tdb && local_pid == sys_getpid())
+               return True;
        tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
        if (!tdb) {
                DEBUG(0,("print_backend_init: Failed to open printing backend database %s\n",
@@ -108,7 +109,7 @@ static struct printjob *print_job_find(int jobid)
                return NULL;
 
        memcpy(&pjob, ret.dptr, sizeof(pjob));
-       free(ret.dptr);
+       SAFE_FREE(ret.dptr);
        return &pjob;
 }
 
@@ -291,7 +292,7 @@ static pid_t get_updating_pid(fstring printer_name)
                return (pid_t)-1;
 
        memcpy(&updating_pid, data.dptr, sizeof(pid_t));
-       free(data.dptr);
+       SAFE_FREE(data.dptr);
 
        if (process_exists(updating_pid))
                return updating_pid;
@@ -568,10 +569,9 @@ BOOL print_job_exists(int jobid)
        return tdb_exists(tdb, print_key(jobid));
 }
 
-
 /****************************************************************************
- Work out which service a jobid is for
note that we have to look up by queue name to ensure that it works for 
+ Work out which service a jobid is for.
Note that we have to look up by queue name to ensure that it works for 
  other than the process that started the job.
 ****************************************************************************/
 
@@ -922,7 +922,7 @@ static int get_queue_status(int snum, print_status_struct *status)
                if (data.dsize == sizeof(print_status_struct)) {
                        memcpy(status, data.dptr, sizeof(print_status_struct));
                }
-               free(data.dptr);
+               SAFE_FREE(data.dptr);
        }
        return status->qcount;
 }
@@ -968,7 +968,7 @@ static int get_total_jobs(int snum)
 }
 
 /***************************************************************************
-start spooling a job - return the jobid
+ Start spooling a job - return the jobid.
 ***************************************************************************/
 
 int print_job_start(struct current_user *user, int snum, char *jobname)
@@ -1116,7 +1116,7 @@ to open spool file %s.\n", pjob.filename));
 }
 
 /****************************************************************************
- Update the number of pages spooled to jobid.
+ Update the number of pages spooled to jobid
 ****************************************************************************/
 
 void print_job_endpage(int jobid)
@@ -1330,7 +1330,7 @@ int print_queue_status(int snum,
                if (data.dsize == sizeof(*status)) {
                        memcpy(status, data.dptr, sizeof(*status));
                }
-               free(data.dptr);
+               SAFE_FREE(data.dptr);
        }
 
        /*
index 60b5e60a81ec06a3829ff3362027ff5b31bf6fd2..aa7fcd0010d114745001161ddebd1b99d18d51ef 100644 (file)
@@ -695,6 +695,7 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
        
        while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
        {
+               DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
                if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
                        return False;
                available_space -= sizeof(uint32);
@@ -1115,6 +1116,7 @@ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
         q_u->handle = *handle;
        init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1);
         q_u->size = size;
+
         return True;
 }
 
index fc6327586948e5b1c99b8438f15db51de81a0fe7..56806823d1df46505727a6dadc9c4651be705c21 100644 (file)
@@ -809,8 +809,10 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
 
        /* Iterate the printer list */
 
-       for (snum=0; snum<n_services; snum++) {
-               if (lp_snum_ok(snum) && lp_print_ok(snum) ) {
+       for (snum=0; snum<n_services; snum++)
+       {
+               if (lp_snum_ok(snum) && lp_print_ok(snum) ) 
+               {
                        WERROR result;
                        NT_PRINTER_INFO_LEVEL *printer = NULL;
 
@@ -818,15 +820,19 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
                        if (!W_ERROR_IS_OK(result))
                                continue;
 
-                       if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername)) {
+                       if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername)) 
+                       {
                                DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
+                               
                                /* all we care about currently is the change_id */
+                               
                                result = mod_a_printer(*printer, 2);
                                if (!W_ERROR_IS_OK(result)) {
                                        DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
                                        dos_errstr(result)));
                                }
                        }
+                       
                        free_a_printer(&printer, 2);
                }
        }
@@ -1000,16 +1006,6 @@ Can't find printer handle we created for printer %s\n", name ));
        }
 
 /*
-       if (printer_default->datatype_ptr != NULL)
-       {
-               unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
-               set_printer_hnd_datatype(handle, datatype);
-       }
-       else
-               set_printer_hnd_datatype(handle, "");
-*/
-       
-       /*
           First case: the user is opening the print server:
 
           Disallow MS AddPrinterWizard if parameter disables it. A Win2k
@@ -3492,10 +3488,26 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
  enum_all_printers_info_1_network.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
+       char *s = name;
+
        DEBUG(4,("enum_all_printers_info_1_network\n"));        
        
+       /* If we respond to a enum_printers level 1 on our name with flags
+          set to PRINTER_ENUM_REMOTE with a list of printers then these
+          printers incorrectly appear in the APW browse list.
+          Specifically the printers for the server appear at the workgroup
+          level where all the other servers in the domain are
+          listed. Windows responds to this call with a
+          WERR_CAN_NOT_COMPLETE so we should do the same. */ 
+
+       if (name[0] == '\\' && name[1] == '\\')
+                s = name + 2;
+
+       if (is_myname_or_ipaddr(s))
+                return WERR_CAN_NOT_COMPLETE;
+
        return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
 }
 
@@ -3582,7 +3594,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
                return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
 
        if (flags & PRINTER_ENUM_NETWORK)
-               return enum_all_printers_info_1_network(buffer, offered, needed, returned);
+               return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
 
        return WERR_OK; /* NT4sp5 does that */
 }
@@ -5247,7 +5259,10 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
                 * bound to the printer, simulating what happens in the Windows arch.
                 */
                if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){
-                       set_driver_init(printer, 2);
+                       if (!set_driver_init(printer, 2)) {
+                               DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
+                                       printer->info_2->drivername));
+                       }
                        msg.flags |= PRINTER_MESSAGE_DRIVER;
                }
        }
@@ -6603,16 +6618,70 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
                        driver_name));
        }
 
-       /* if driver is not 9x, delete existing driver init data */
+       /*
+        * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
+        * decide if the driver init data should be deleted. The rules are:
+        *  1) never delete init data if it is a 9x driver, they don't use it anyway
+        *  2) delete init data only if there is no 2k/Xp driver
+        *  3) always delete init data
+        * The generalized rule is always use init data from the highest order driver.
+        * It is necessary to follow the driver install by an initialization step to
+        * finish off this process.
+       */
+       if (level == 3)
+               version = driver.info_3->cversion;
+       else if (level == 6)
+               version = driver.info_6->version;
+       else
+               version = -1;
+       switch (version) {
+               /*
+                * 9x printer driver - never delete init data
+               */
+               case 0: 
+                       DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
+                                       driver_name));
+                       break;
+               
+               /*
+                * Nt or 2k (compatiblity mode) printer driver - only delete init data if
+                * there is no 2k/Xp driver init data for this driver name.
+               */
+               case 2:
+               {
+                       NT_PRINTER_DRIVER_INFO_LEVEL driver1;
 
-       if ((level == 3 && driver.info_3->cversion != 0) ||
-                       (level == 6 && driver.info_6->version  != 0)) {
+                       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
+                               /*
+                                * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
+                               */
                if (!del_driver_init(driver_name))
-                       DEBUG(3,("_spoolss_addprinterdriver: del_driver_init(%s) failed!\n", driver_name));
+                                       DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
        } else {
-               DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n", driver_name));
+                               /*
+                                * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
+                               */
+                               free_a_printer_driver(driver1,3);
+                               DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n", 
+                                               driver_name));
+                       }
+               }
+               break;
+
+               /*
+                * 2k or Xp printer driver - always delete init data
+               */
+               case 3: 
+                       if (!del_driver_init(driver_name))
+                               DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
+                       break;
+
+               default:
+                       DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
+                       break;
        }
 
+       
  done:
        free_a_printer_driver(driver, level);
        return err;
@@ -6756,23 +6825,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
        if ( (in_value_len==0) && (in_data_len==0) ) {
                DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
-#if 0
-               /*
-                * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
-                * if this parameter size doesn't exist.
-                * Ok - my opinion here is that the client is not asking for the greatest
-                * possible size of all the parameters, but is asking specifically for the size needed
-                * for this specific parameter. In that case we can remove the loop below and
-                * simplify this lookup code considerably. JF - comments welcome. JRA.
-                */
-
-               if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
-                       SAFE_FREE(data);
-                       free_a_printer(&printer, 2);
-                       return WERR_NO_MORE_ITEMS;
-               }
-#endif
-
                SAFE_FREE(data);
 
                param_index=0;
@@ -7925,7 +7977,7 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
 
        unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
 
-       if (get_short_archi(short_archi, long_archi)==FALSE)
+       if (get_short_archi(short_archi, long_archi)==False)
                return WERR_INVALID_ENVIRONMENT;
 
        if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
@@ -7958,6 +8010,7 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
        NEW_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
+       WERROR result;
 
        /* that's an [in out] buffer */
        spoolss_move_buffer(q_u->buffer, &r_u->buffer);
@@ -7969,11 +8022,11 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
 
        switch(level) {
        case 1:
-               return getprintprocessordirectory_level_1
+               result = getprintprocessordirectory_level_1
                  (&q_u->name, &q_u->environment, buffer, offered, needed);
        default:
-               return WERR_UNKNOWN_LEVEL;
+               result = WERR_UNKNOWN_LEVEL;
        }
 
-       return WERR_ACCESS_DENIED;
+       return result;
 }