diff options
author | Gerald Carter <jerry@samba.org> | 2002-06-24 19:51:23 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2002-06-24 19:51:23 +0000 |
commit | 900fb62238be30cdc87bfd2bede6fdff611ebae5 (patch) | |
tree | cb5073f32d4faf1a3eee3392da04b3b09424d10f /source3 | |
parent | 24b67730bf7bbf4414df99129a3cc20aa93dc0da (diff) | |
download | samba-900fb62238be30cdc87bfd2bede6fdff611ebae5.tar.gz samba-900fb62238be30cdc87bfd2bede6fdff611ebae5.tar.bz2 samba-900fb62238be30cdc87bfd2bede6fdff611ebae5.zip |
printing merge from SAMBA_2_2. Ther server code looks to be in sync now.
Mostly formatting and s/free/SAFE_FREE/g changes with the two exceptions
being
* John driver init changes
* Tim's printer enumeration bug fix
(This used to be commit f7536762863811f96364e8acd3716bdb7d665bbf)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/printing/nt_printing.c | 19 | ||||
-rw-r--r-- | source3/printing/pcap.c | 22 | ||||
-rw-r--r-- | source3/printing/print_cups.c | 2 | ||||
-rw-r--r-- | source3/printing/printing.c | 20 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 137 |
6 files changed, 131 insertions, 71 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index ecf873c1ba..08d5ea430a 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -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; } diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 920c6f354e..01e03c7c6b 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -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; diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index b5315e10b2..51ebb739a3 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -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); } diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 47fc019d64..aa9df5e47f 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -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); } /* diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 60b5e60a81..aa7fcd0010 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -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; } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index fc63275869..56806823d1 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -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; } |