intermediate work on DeletePrinterDriverEx(). This call
authorGerald Carter <jerry@samba.org>
Thu, 11 Jul 2002 01:54:26 +0000 (01:54 +0000)
committerGerald Carter <jerry@samba.org>
Thu, 11 Jul 2002 01:54:26 +0000 (01:54 +0000)
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

source/include/rpc_spoolss.h
source/printing/nt_printing.c
source/rpc_server/srv_spoolss_nt.c

index 82062d52786c2cccac410a78fcce8a548a12e5fc..18cf35f440efda15f553ba2cc757dc3d25c4d9c8 100755 (executable)
@@ -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 */
index 2abe27b95d71270a7e86598b2f4108b69237a3c5..fe90625e78a3a40bb867abf974e63992de99f583 100644 (file)
@@ -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; snum<n_services; snum++
        {
-
-               dbuf = tdb_fetch(tdb_printers, kbuf);
-               if (!dbuf.dptr) 
+               if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
                        continue;
-
-               if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0) 
+               
+               if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) )
                        continue;
+               
+               if ( !StrCaseCmp(i->name, 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; version<DRIVER_MAX_VERSION; version++ )
+       {
+               /* get the list of drivers */
                
-               DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
-                       info.printername, info.drivername));
+               list = NULL;
+               ndrivers = get_ntdrivers(&list, info->environment, 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; i<ndrivers; i++) 
                {
-                       DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
-                               info.printername, driver));
-                       return True;
+                       DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
+                       
+                       ZERO_STRUCT(driver);
+                       
+                       if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], 
+                               info->environment, 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;
 }
 /****************************************************************************
index 70964ce6681973f710604d7dca691f4744b3fb66..8acdd9d5ab4de0c0e3692d0b8e5098d113d95139 100644 (file)
@@ -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<MAX_VERSION; version++) {
+       for (version=0; version<DRIVER_MAX_VERSION; version++) {
                list=NULL;
                ndrivers=get_ntdrivers(&list, architecture, version);
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6009,9 +6018,7 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
 
        *returned=0;
 
-#define MAX_VERSION 4
-
-       for (version=0; version<MAX_VERSION; version++) {
+       for (version=0; version<DRIVER_MAX_VERSION; version++) {
                list=NULL;
                ndrivers=get_ntdrivers(&list, architecture, version);
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6091,9 +6098,7 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
 
        *returned=0;
 
-#define MAX_VERSION 4
-
-       for (version=0; version<MAX_VERSION; version++) {
+       for (version=0; version<DRIVER_MAX_VERSION; version++) {
                list=NULL;
                ndrivers=get_ntdrivers(&list, architecture, version);
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));