summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-07-11 03:27:12 +0000
committerGerald Carter <jerry@samba.org>2002-07-11 03:27:12 +0000
commit0aadcff8ec1caa7e8a8cc9c5738bc8d57be7b24f (patch)
tree8ecd1f3c024b7045ef7c6175ac1426aac153e678 /source3
parent496e85dd812b932caf5e6169e03df6b31a378966 (diff)
downloadsamba-0aadcff8ec1caa7e8a8cc9c5738bc8d57be7b24f.tar.gz
samba-0aadcff8ec1caa7e8a8cc9c5738bc8d57be7b24f.tar.bz2
samba-0aadcff8ec1caa7e8a8cc9c5738bc8d57be7b24f.zip
all that is left to do is to actually perform the
file deletion now. I have the file list. One more commit should do it. (This used to be commit 7207662504f585352b0ceeb99f8998ef58db7f15)
Diffstat (limited to 'source3')
-rw-r--r--source3/printing/nt_printing.c170
-rw-r--r--source3/rpc_parse/parse_spoolss.c4
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c28
3 files changed, 183 insertions, 19 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index fe90625e78..17a16b84bc 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -3461,21 +3461,130 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i )
return False;
}
+
+/**********************************************************************
+ Check to see if a ogiven file is in use by *info
+ *********************************************************************/
+
+static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
+{
+ char *s;
+
+ if ( !info )
+ return False;
+
+ if ( strequal(file, info->driverpath) )
+ return True;
+
+ if ( strequal(file, info->datafile) )
+ return True;
+
+ if ( strequal(file, info->configfile) )
+ return True;
+
+ if ( strequal(file, info->helpfile) )
+ return True;
+
+ s = (char*) info->dependentfiles;
+
+ if ( s ) {
+ while ( *s )
+ {
+ if ( strequal(file, s) )
+ return True;
+ s += strlen(s) + 1;
+ }
+ }
+
+ return False;
+
+}
+
+/**********************************************************************
+ Utility function to remove the dependent file pointed to by the
+ input parameter from the list
+ *********************************************************************/
+
+static void trim_dependent_file( char* s )
+{
+ char *p;
+
+ /* set p to the next character string in the list */
+
+ p = s + strlen( s ) + 1;
+
+ /* check to see that we have another string to copy back */
+
+ if ( *p == '\0' )
+ {
+ /* loop over s copying characters from p to s */
+ while ( *p!='\0' && *(p+1)!='\0' )
+ *s++ = *p++;
+ }
+
+ /* add the two trailing NULL's */
+
+ *s = '\0';
+ *(s+1) = '\0';
+}
+
/**********************************************************************
Check if any of the files used by src are also used by drv
*********************************************************************/
-static BOOL check_driver_file_overlap( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
+static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
{
+ BOOL in_use = False;
+ char *s;
-
- return False;
+ if ( !src || !drv )
+ return False;
+
+ /* check each file. Remove it from the src structure if it overlaps */
+
+ if ( drv_file_in_use(src->driverpath, drv) ) {
+ in_use = True;
+ fstrcpy( src->driverpath, "" );
+ }
+
+ if ( drv_file_in_use(src->datafile, drv) ) {
+ in_use = True;
+ fstrcpy( src->datafile, "" );
+ }
+
+ if ( drv_file_in_use(src->configfile, drv) ) {
+ in_use = True;
+ fstrcpy( src->configfile, "" );
+ }
+
+ s = (char*)src->dependentfiles;
+
+ if ( s ) {
+ while ( *s )
+ {
+ if ( drv_file_in_use(s, drv) ) {
+ in_use = True;
+ trim_dependent_file( s );
+ }
+ else
+ s += strlen(s) + 1;
+ }
+ }
+
+
+ return in_use;
}
/****************************************************************************
Determine whether or not a particular driver files are currently being
- used by any other driver. Requires using the full path from [print$]
+ used by any other driver.
+
+ Return value is True if any files were in use by other drivers
+ and False otherwise.
+
+ Upon return, *info has been modified to only contain the driver files
+ which are not in use
****************************************************************************/
BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
@@ -3500,7 +3609,7 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
ndrivers, info->environment, version));
- if(ndrivers == -1)
+ if (ndrivers == -1)
continue;
/* check each driver for overlap in files */
@@ -3512,18 +3621,23 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
ZERO_STRUCT(driver);
if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i],
- info->environment, version)) )
+ info->environment, version)) )
{
SAFE_FREE(list);
return True;
}
/* check if d2 uses any files from d1 */
+ /* only if this is a different driver than the one being deleted */
- if ( check_driver_file_overlap(info, driver.info_3) ) {
- free_a_printer_driver(driver, 3);
- SAFE_FREE( list );
- return True;
+ if ( !strequal(info->name, driver.info_3->name)
+ || (info->cversion != driver.info_3->cversion) )
+ {
+ if ( trim_overlap_drv_files(info, driver.info_3) ) {
+ free_a_printer_driver(driver, 3);
+ SAFE_FREE( list );
+ return True;
+ }
}
free_a_printer_driver(driver, 3);
@@ -3545,7 +3659,31 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i )
{
-
+ char *s;
+
+ if ( !i )
+ return NT_STATUS_ACCESS_DENIED;
+
+ DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", i->name, i->cversion));
+
+
+ if ( *i->driverpath )
+ DEBUG(10,("deleting [%s]\n", i->driverpath));
+ if ( *i->configfile )
+ DEBUG(10,("deleting [%s]\n", i->configfile));
+ if ( *i->datafile )
+ DEBUG(10,("deleting [%s]\n", i->datafile));
+ if ( *i->helpfile )
+ DEBUG(10,("deleting [%s]\n", i->helpfile));
+
+ s = (char*)i->dependentfiles;
+
+ if ( s ) {
+ while ( *s ) {
+ DEBUG(10,("deleting dependent file [%s]\n", s));
+ s += strlen( s ) + 1;
+ }
+ }
return NT_STATUS_OK;
}
@@ -3565,7 +3703,9 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil
get_short_archi(arch, i->environment);
slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
arch, i->cversion, i->name);
- DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
+
+ DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
+ key, delete_files ? "TRUE" : "FALSE" ));
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
@@ -3575,9 +3715,6 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil
return WERR_ACCESS_DENIED;
}
- 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
@@ -3587,6 +3724,9 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil
if ( delete_files )
delete_driver_files( i );
+ DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
+ i->name));
+
return WERR_OK;
}
/****************************************************************************
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index c74249878a..b10a5c4377 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -1516,6 +1516,10 @@ BOOL spoolss_io_q_deleteprinterdriverex(char *desc, SPOOL_Q_DELETEPRINTERDRIVERE
return False;
if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
return False;
+
+ if (!prs_align(ps))
+ return False;
+
if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
return False;
if(!prs_uint32("version ", ps, depth, &q_u->version))
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 8acdd9d5ab..a37d8e9c19 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -1590,6 +1590,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
NT_PRINTER_DRIVER_INFO_LEVEL info;
int version;
uint32 flags = q_u->delete_flags;
+ BOOL delete_files;
unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
@@ -1614,11 +1615,30 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
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;
+ /*
+ * we have a couple of cases to consider.
+ * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
+ * then the delete should fail if **any** files overlap with
+ * other drivers
+ * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
+ * non-overlapping files
+ * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
+ * is set, the do not delete any files
+ * Refer to MSDN docs on DeletePrinterDriverEx() for details.
+ */
+
+ delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
+
+ if ( delete_files )
+ {
+ /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
+
+ if ( printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) )
+ /* no idea of the correct error here */
+ return WERR_ACCESS_DENIED;
+ }
- return delete_printer_driver(info.info_3, True);
+ return delete_printer_driver(info.info_3, delete_files);
}