From 496e85dd812b932caf5e6169e03df6b31a378966 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Jul 2002 01:54:26 +0000 Subject: intermediate work on DeletePrinterDriverEx(). This call will actually delete driver files ( not yet though I don't think). Just wanted to get it in since Jeremy and I are both working on nt_printing.c (This used to be commit 3fa6c3132950c9ff1c6a532d8264ee34a6b2b0ff) --- source3/include/rpc_spoolss.h | 17 +-- source3/printing/nt_printing.c | 217 ++++++++++++++++++++++++------------ source3/rpc_server/srv_spoolss_nt.c | 43 +++---- 3 files changed, 180 insertions(+), 97 deletions(-) (limited to 'source3') diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 82062d5278..18cf35f440 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -401,16 +401,19 @@ PRINTER_MESSAGE_INFO; /* FLAGS for SPOOLSS_DELETEPRINTERDRIVEREX */ -#define DPD_DELETE_UNUSED_FILES 0x00000001 -#define DPD_DELETE_SPECIFIC_VERSION 0x00000002 -#define DPD_DELETE_ALL_FILES 0x00000004 +#define DPD_DELETE_UNUSED_FILES 0x00000001 +#define DPD_DELETE_SPECIFIC_VERSION 0x00000002 +#define DPD_DELETE_ALL_FILES 0x00000004 + +#define DRIVER_ANY_VERSION 0xffffffff +#define DRIVER_MAX_VERSION 4 /* FLAGS for SPOOLSS_ADDPRINTERDRIVEREX */ -#define APD_STRICT_UPGRADE 0x00000001 -#define APD_STRICT_DOWNGRADE 0x00000002 -#define APD_COPY_ALL_FILES 0x00000004 -#define APD_COPY_NEW_FILES 0x00000008 +#define APD_STRICT_UPGRADE 0x00000001 +#define APD_STRICT_DOWNGRADE 0x00000002 +#define APD_COPY_ALL_FILES 0x00000004 +#define APD_COPY_NEW_FILES 0x00000008 /* this struct is undocumented */ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 2abe27b95d..fe90625e78 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1683,13 +1683,13 @@ static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver) /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch) +static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring driver, fstring arch) { NT_PRINTER_DRIVER_INFO_LEVEL_3 info; ZERO_STRUCT(info); - fstrcpy(info.name, in_prt); + fstrcpy(info.name, driver); fstrcpy(info.defaultdatatype, "RAW"); fstrcpy(info.driverpath, ""); @@ -1710,7 +1710,7 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version) +static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, fstring arch, uint32 version) { NT_PRINTER_DRIVER_INFO_LEVEL_3 driver; TDB_DATA kbuf, dbuf; @@ -1721,21 +1721,19 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, ZERO_STRUCT(driver); - get_short_archi(architecture, in_arch); + get_short_archi(architecture, arch); - DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt)); + DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername)); - slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt); + slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername); kbuf.dptr = key; kbuf.dsize = strlen(key)+1; dbuf = tdb_fetch(tdb_drivers, kbuf); -#if 0 - if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch); -#else - if (!dbuf.dptr) return WERR_ACCESS_DENIED; -#endif + if (!dbuf.dptr) + return WERR_ACCESS_DENIED; + len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", &driver.cversion, driver.name, @@ -1771,7 +1769,7 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, if (len != dbuf.dsize) { SAFE_FREE(driver.dependentfiles); - return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch); + return get_a_printer_driver_3_default(info_ptr, drivername, arch); } *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver)); @@ -3335,17 +3333,31 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) /**************************************************************************** ****************************************************************************/ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring printername, fstring architecture, uint32 version) + fstring drivername, fstring architecture, uint32 version) { WERROR result; switch (level) { case 3: - { - result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version); + /* Sometime we just want any version of the driver */ + + if ( version == DRIVER_ANY_VERSION ) { + /* look for Win2k first and then for NT4 */ + result = get_a_printer_driver_3(&driver->info_3, drivername, + architecture, 3); + + if ( !W_ERROR_IS_OK(result) ) { + result = get_a_printer_driver_3( &driver->info_3, + drivername, architecture, 2 ); + } + } + else { + result = get_a_printer_driver_3(&driver->info_3, drivername, + architecture, version); + } break; - } + default: result=W_ERROR(1); break; @@ -3353,6 +3365,7 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, if (W_ERROR_IS_OK(result)) dump_a_printer_driver(*driver, level); + return result; } @@ -3411,91 +3424,144 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) Determine whether or not a particular driver is currently assigned to a printer ****************************************************************************/ -BOOL printer_driver_in_use (char *arch, char *driver) + +BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) { - TDB_DATA kbuf, newkey, dbuf; - NT_PRINTER_INFO_LEVEL_2 info; - int ret; + int snum; + int n_services = lp_numservices(); + NT_PRINTER_INFO_LEVEL *printer = NULL; - if (!tdb_printers) - if (!nt_printing_init()) - return False; + if ( !i ) + return False; - DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n")); + DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n")); /* loop through the printers.tdb and check for the drivername */ - for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr; - newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) + + for (snum=0; snumname, printer->info_2->drivername) ) { + free_a_printer( &printer, 2 ); + return True; + } + + free_a_printer( &printer, 2 ); + } + + DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n")); + + /* report that the driver is not in use by default */ + + return False; +} - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff", - &info.attributes, - &info.priority, - &info.default_priority, - &info.starttime, - &info.untiltime, - &info.status, - &info.cjobs, - &info.averageppm, - &info.changeid, - &info.c_setprinter, - &info.setuptime, - info.servername, - info.printername, - info.sharename, - info.portname, - info.drivername, - info.comment, - info.location, - info.sepfile, - info.printprocessor, - info.datatype, - info.parameters); +/********************************************************************** + Check if any of the files used by src are also used by drv + *********************************************************************/ - SAFE_FREE(dbuf.dptr); +static BOOL check_driver_file_overlap( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, + NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv ) +{ + - if (ret == -1) { - DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n", - info.printername)); - continue; - } + return False; +} + +/**************************************************************************** + Determine whether or not a particular driver files are currently being + used by any other driver. Requires using the full path from [print$] +****************************************************************************/ + +BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) +{ + int i; + int ndrivers; + uint32 version; + fstring *list = NULL; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + + /* loop over all driver versions */ + + DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n")); + + for ( version=0; versionenvironment, version); + + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", + ndrivers, info->environment, version)); + + if(ndrivers == -1) + continue; - if (strcmp(info.drivername, driver) == 0) + /* check each driver for overlap in files */ + + for (i=0; ienvironment, version)) ) + { + SAFE_FREE(list); + return True; + } + + /* check if d2 uses any files from d1 */ + + if ( check_driver_file_overlap(info, driver.info_3) ) { + free_a_printer_driver(driver, 3); + SAFE_FREE( list ); + return True; + } + + free_a_printer_driver(driver, 3); } + + SAFE_FREE(list); } - DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n")); - + DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n")); - /* report that the driver is in use by default */ return False; } +/**************************************************************************** + Actually delete the driver files. Make sure that + printer_driver_files_in_use() return False before calling + this. +****************************************************************************/ + +static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i ) +{ + + + return NT_STATUS_OK; +} + /**************************************************************************** Remove a printer driver from the TDB. This assumes that the the driver was previously looked up. ***************************************************************************/ -WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i) +WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_files) { pstring key; fstring arch; TDB_DATA kbuf; - + /* delete the tdb data first */ + get_short_archi(arch, i->environment); slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, arch, i->cversion, i->name); @@ -3512,6 +3578,15 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i) DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n", i->name)); + /* + * now delete any associated files if delete_files == True + * even if this part failes, we return succes because the + * driver doesn not exist any more + */ + + if ( delete_files ) + delete_driver_files( i ); + return WERR_OK; } /**************************************************************************** diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 70964ce668..8acdd9d5ab 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -1562,16 +1562,21 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER /* this is what NT returns */ return WERR_INVALID_ENVIRONMENT; } + + /* if they said "Windows NT x86", then try for version 2 & 3 */ + + if ( version == 2 ) + version = DRIVER_ANY_VERSION; ZERO_STRUCT(info); + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) return WERR_UNKNOWN_PRINTER_DRIVER; - - if (printer_driver_in_use(arch, driver)) + if (printer_driver_in_use(info.info_3)) return WERR_PRINTER_DRIVER_IN_USE; - return delete_printer_driver(info.info_3); + return delete_printer_driver(info.info_3, False); } /******************************************************************** @@ -1584,6 +1589,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV fstring arch; NT_PRINTER_DRIVER_INFO_LEVEL info; int version; + uint32 flags = q_u->delete_flags; unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); @@ -1594,18 +1600,25 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV return WERR_INVALID_ENVIRONMENT; } - if (q_u->delete_flags & DPD_DELETE_SPECIFIC_VERSION) + if ( flags & DPD_DELETE_SPECIFIC_VERSION ) version = q_u->version; + else if ( version == 2 ) + /* if they said "Windows NT x86", then try for version 2 & 3 */ + version = DRIVER_ANY_VERSION; ZERO_STRUCT(info); - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) - return WERR_UNKNOWN_PRINTER_DRIVER; + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) + return WERR_UNKNOWN_PRINTER_DRIVER; - if (printer_driver_in_use(arch, driver)) + if ( printer_driver_in_use(info.info_3) ) return WERR_PRINTER_DRIVER_IN_USE; + + if ( printer_driver_files_in_use(info.info_3) ) + /* no idea of the correct error here */ + return WERR_ACCESS_DENIED; - return delete_printer_driver(info.info_3); + return delete_printer_driver(info.info_3, True); } @@ -5869,8 +5882,6 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u { POLICY_HND *handle = &q_u->handle; uint32 jobid = q_u->jobid; -/* uint32 level = q_u->level; - notused. */ -/* JOB_INFO *ctr = &q_u->ctr; - notused. */ uint32 command = q_u->command; struct current_user user; @@ -5928,9 +5939,7 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture *returned=0; -#define MAX_VERSION 4 - - for (version=0; version