Move towards getting W2k p&p to upload NT4.x drivers. Still doesn't work -
authorJeremy Allison <jra@samba.org>
Fri, 15 Sep 2000 00:15:10 +0000 (00:15 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 15 Sep 2000 00:15:10 +0000 (00:15 +0000)
not sure why (JF - a glance at this would be appreciated). Removed code
that JF objected to with enumprinterdata. Added translations to/from
level 6 - but Win2k still not happy... hmmm...
Jeremy.
(This used to be commit e5d98ba9e97eb16337ff6c49f799e130844ae72e)

source3/include/proto.h
source3/printing/nt_printing.c
source3/rpc_parse/parse_spoolss.c
source3/rpc_server/srv_spoolss_nt.c

index 2d04cb2a93b6d1c151fce8041011d45d4474143b..cbee378e2124f99996e3047975dfbd75690f385b 100644 (file)
@@ -2771,6 +2771,7 @@ BOOL new_smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, i
 BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ;
 BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) ;
 BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth);
+BOOL new_smb_io_printer_driver_info_6(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth);
 BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth);
 BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth);
 BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth);
@@ -2792,6 +2793,7 @@ uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info);
 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info);
 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info);
 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info);
+uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info);
 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info);
 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info);
 uint32 spoolss_size_form_1(FORM_1 *info);
index 255418a0ed3b872fe229cfeb95c6e147cea09045..a3ae6eb0f27f476467c8309f2631c4f1c3d8b0b5 100644 (file)
@@ -403,7 +403,67 @@ static void clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *drive
 ****************************************************************************/
 static void clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
 {
+       fstring architecture;
+       fstring new_name;
+       char *p;
+       int i;
+       
+       /* jfm:7/16/2000 the client always sends the cversion=0.
+        * The server should check which version the driver is by reading the PE header
+        * of driver->driverpath.
+        *
+        * For Windows 95/98 the version is 0 (so the value sent is correct)
+        * For Windows NT (the architecture doesn't matter)
+        *      NT 3.1: cversion=0
+        *      NT 3.5/3.51: cversion=1
+        *      NT 4: cversion=2
+        *      NT2K: cversion=3
+        */
+
+       get_short_archi(architecture, driver->environment);
+
+       /* if it's Windows 95/98, we keep the version at 0
+        * jfmxxx: I need to redo that more correctly for NT2K.
+        */
+        
+       if (StrCaseCmp(driver->environment, "Windows 4.0")==0)
+               driver->version=0;
+       else
+               driver->version=2;
+
+       /* clean up the driver name.
+        * we can get .\driver.dll
+        * or worse c:\windows\system\driver.dll !
+        */
+       /* using an intermediate string to not have overlaping memcpy()'s */
+       if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
+               fstrcpy(new_name, p+1);
+               fstrcpy(driver->driverpath, new_name);
+       }
+
+       if ((p = strrchr(driver->datafile,'\\')) != NULL) {
+               fstrcpy(new_name, p+1);
+               fstrcpy(driver->datafile, new_name);
+       }
+
+       if ((p = strrchr(driver->configfile,'\\')) != NULL) {
+               fstrcpy(new_name, p+1);
+               fstrcpy(driver->configfile, new_name);
+       }
 
+       if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
+               fstrcpy(new_name, p+1);
+               fstrcpy(driver->helpfile, new_name);
+       }
+
+       if (driver->dependentfiles) {
+               for (i=0; *driver->dependentfiles[i]; i++) {
+                       if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
+                               fstrcpy(new_name, p+1);
+                               fstrcpy(driver->dependentfiles[i], new_name);
+                       }
+               }
+       }
 }
 
 /****************************************************************************
@@ -671,6 +731,8 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
 
        slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
 
+       DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
+
        buf = NULL;
        len = buflen = 0;
 
@@ -708,6 +770,9 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
        
        ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
 
+       if (ret)
+               DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
+
        safe_free(buf);
        return ret;
 }
@@ -720,6 +785,7 @@ static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
 
        ZERO_STRUCT(info3);
        info3.cversion = driver->version;
+       fstrcpy(info3.name,driver->name);
        fstrcpy(info3.environment,driver->environment);
        fstrcpy(info3.driverpath,driver->driverpath);
        fstrcpy(info3.datafile,driver->datafile);
@@ -1819,8 +1885,7 @@ uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
        {
                case 3: 
                {
-                       success=get_a_printer_driver_3(&driver->info_3, printername,
-                                                      architecture, version);
+                       success=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
                        break;
                }
                default:
index 953124ebe464d7de12b2cb335ce28a148f22a6cb..cb24a9793872aeb06f4560adbe6e6f8018ce1379 100644 (file)
@@ -1508,6 +1508,14 @@ static uint32 size_of_uint32(uint32 *value)
 {
        return (sizeof(*value));
 }
+/*******************************************************************
+ * return the length of a NTTIME (obvious, but the code is clean)
+ ********************************************************************/
+static uint32 size_of_nttime(NTTIME *value)
+{
+       return (sizeof(*value));
+}
+
 /*******************************************************************
  * return the length of a UNICODE string in number of char, includes:
  * - the leading zero
@@ -1886,7 +1894,7 @@ static BOOL new_smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEV
 ********************************************************************/  
 BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "smb_io_printer_info_0");
        depth++;        
@@ -2087,7 +2095,7 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i
 ********************************************************************/  
 BOOL new_smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_printer_info_3");
        depth++;        
@@ -2107,7 +2115,7 @@ BOOL new_smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *i
 ********************************************************************/  
 BOOL new_smb_io_port_info_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_port_info_1");
        depth++;        
@@ -2125,7 +2133,7 @@ BOOL new_smb_io_port_info_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, i
 ********************************************************************/  
 BOOL new_smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_port_info_2");
        depth++;        
@@ -2151,7 +2159,7 @@ BOOL new_smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, i
 ********************************************************************/
 BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_1");
        depth++;        
@@ -2170,7 +2178,7 @@ BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INF
 ********************************************************************/
 BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_2");
        depth++;        
@@ -2199,7 +2207,7 @@ BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INF
 ********************************************************************/
 BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_3");
        depth++;        
@@ -2232,13 +2240,71 @@ BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INF
        return True;
 }
 
+/*******************************************************************
+ Parse a DRIVER_INFO_6 structure.
+********************************************************************/
+BOOL new_smb_io_printer_driver_info_6(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
+{
+       prs_struct *ps=&buffer->prs;
+
+       prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_6");
+       depth++;        
+       
+       buffer->struct_start=prs_offset(ps);
+
+       if (!prs_uint32("version", ps, depth, &info->version))
+               return False;
+       if (!new_smb_io_relstr("name", buffer, depth, &info->name))
+               return False;
+       if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
+               return False;
+       if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
+               return False;
+       if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
+               return False;
+       if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
+               return False;
+       if (!new_smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
+               return False;
+
+       if (!new_smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
+               return False;
+
+       if (!new_smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
+               return False;
+       if (!new_smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
+               return False;
+
+       if (!new_smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
+               return False;
+
+       if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
+               return False;
+       if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
+               return False;
+
+       if (!prs_uint32("driver_version", ps, depth, &info->driver_version))
+               return False;
+
+       if (!new_smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
+               return False;
+       if (!new_smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
+               return False;
+       if (!new_smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
+               return False;
+       if (!new_smb_io_relstr("provider", buffer, depth, &info->provider))
+               return False;
+       
+       return True;
+}
+
 
 /*******************************************************************
  Parse a JOB_INFO_1 structure.
 ********************************************************************/  
 BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_job_info_1");
        depth++;        
@@ -2281,7 +2347,7 @@ BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int
 BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
 {      
        uint pipo=0;
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
        
        prs_debug(ps, depth, desc, "new_smb_io_job_info_2");
        depth++;        
@@ -2346,7 +2412,7 @@ BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int
 ********************************************************************/  
 BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
        
        prs_debug(ps, depth, desc, "new_smb_io_form_1");
        depth++;
@@ -2496,7 +2562,7 @@ uint32 new_get_buffer_size(NEW_BUFFER *buffer)
 ********************************************************************/  
 BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_driverdir_1");
        depth++;
@@ -2514,7 +2580,7 @@ BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *
 ********************************************************************/  
 BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_port_1");
        depth++;
@@ -2532,7 +2598,7 @@ BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int de
 ********************************************************************/  
 BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "new_smb_io_port_2");
        depth++;
@@ -2558,7 +2624,7 @@ BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int de
 ********************************************************************/  
 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
        depth++;        
@@ -2575,7 +2641,7 @@ BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR
 ********************************************************************/  
 BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
        depth++;        
@@ -2609,7 +2675,7 @@ BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *
 ********************************************************************/  
 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
 {
-       prs_struct *ps=&(buffer->prs);
+       prs_struct *ps=&buffer->prs;
 
        prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
        depth++;        
@@ -2805,6 +2871,53 @@ uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
        return size;
 }
 
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
+{
+       int size=0;
+       uint16 *string;
+       int i=0;
+
+       size+=size_of_uint32( &info->version ); 
+       size+=size_of_relative_string( &info->name );
+       size+=size_of_relative_string( &info->architecture );
+       size+=size_of_relative_string( &info->driverpath );
+       size+=size_of_relative_string( &info->datafile );
+       size+=size_of_relative_string( &info->configfile );
+       size+=size_of_relative_string( &info->helpfile );
+
+       string=info->dependentfiles;
+       if (string) {
+               for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
+       }
+
+       size+=size_of_relative_string( &info->monitorname );
+       size+=size_of_relative_string( &info->defaultdatatype );
+       
+       string=info->previousdrivernames;
+       if (string) {
+               for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
+       }
+
+       size+=size_of_nttime(&info->driver_date);
+       size+=size_of_uint32( &info->driver_version );  
+       size+=size_of_relative_string( &info->mfgname );
+       size+=size_of_relative_string( &info->oem_url );
+       size+=size_of_relative_string( &info->hardware_id );
+       size+=size_of_relative_string( &info->provider );
+
+       i=i+2; /* to count all chars including the leading zero */
+       i=2*i; /* because we need the value in bytes */
+       i=i+4; /* the offset pointer size */
+
+       size+=i;
+
+       return size;
+}
+
+
 /*******************************************************************
 return the size required by a struct in the stream
 ********************************************************************/  
index 4727ee8092de4de5ffeb3c71562217e06bba8d20..c22767c43ac14950553f531de2db0d21accc68ad 100644 (file)
@@ -535,11 +535,7 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
 
        prs_set_offset(ps, old_offset);
 
-#if 0 /* JRATEST */
-       buffer->string_at_end = buffer_size;
-#else
        buffer->string_at_end=prs_data_size(ps);
-#endif
 
        return True;
 }
@@ -1838,10 +1834,7 @@ static DEVICEMODE *construct_dev_mode(int snum, char *servername)
 
        if (printer->info_2->devmode)
                ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
-#if 0 /* JFMTEST */
-       else
-               ntdevmode = construct_nt_devicemode(printer->info_2->printername);
-#endif
+
        if (ntdevmode == NULL)
                goto fail;
 
@@ -1998,10 +1991,29 @@ static BOOL construct_printer_info_3(fstring servername,
 
        ZERO_STRUCTP(printer);
        
-       printer->flags = 4; /* This is the offset to the SEC_DESC. */
+       printer->flags = 4; /* These are the components of the SD we are returning. */
        if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
                /* steal the printer info sec_desc structure.  [badly done]. */
                printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
+
+#if 0
+               /*
+                * Set the flags for the components we are returning.
+                */
+
+               if (printer->secdesc->owner_sid)
+                       printer->flags |= OWNER_SECURITY_INFORMATION;
+
+               if (printer->secdesc->grp_sid)
+                       printer->flags |= GROUP_SECURITY_INFORMATION;
+
+               if (printer->secdesc->dacl)
+                       printer->flags |= DACL_SECURITY_INFORMATION;
+
+               if (printer->secdesc->sacl)
+                       printer->flags |= SACL_SECURITY_INFORMATION;
+#endif
+
                ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
                ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
                ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
@@ -2643,6 +2655,8 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
        pstring temp_configfile;
        pstring temp_helpfile;
 
+       ZERO_STRUCTP(info);
+
        info->version=driver.info_3->cversion;
 
        init_unistr( &info->name, driver.info_3->name );        
@@ -2675,7 +2689,7 @@ static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst
 {      
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
-uint32 status=0;
+       uint32 status=0;
        ZERO_STRUCT(driver);
 
        status=get_a_printer(&printer, 2, lp_servicename(snum) );
@@ -2697,6 +2711,84 @@ uint32 status=0;
        return NT_STATUS_NO_PROBLEMO;
 }
 
+/********************************************************************
+ * construct_printer_info_6
+ * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
+ ********************************************************************/
+
+static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
+{
+       pstring temp_driverpath;
+       pstring temp_datafile;
+       pstring temp_configfile;
+       pstring temp_helpfile;
+       fstring nullstr;
+
+       ZERO_STRUCTP(info);
+       memset(&nullstr, '\0', sizeof(fstring));
+
+       info->version=driver.info_3->cversion;
+
+       init_unistr( &info->name, driver.info_3->name );        
+       init_unistr( &info->architecture, driver.info_3->environment );
+
+       snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);                 
+       init_unistr( &info->driverpath, temp_driverpath );
+
+       snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile); 
+       init_unistr( &info->datafile, temp_datafile );
+
+       snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+       init_unistr( &info->configfile, temp_configfile );      
+
+       snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
+       init_unistr( &info->helpfile, temp_helpfile );
+
+       init_unistr( &info->monitorname, driver.info_3->monitorname );
+       init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
+
+       info->dependentfiles=NULL;
+       init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
+
+       info->previousdrivernames=NULL;
+       init_unistr_array(&info->previousdrivernames, &nullstr, servername);
+
+       init_unistr( &info->mfgname, "");
+       init_unistr( &info->oem_url, "");
+       init_unistr( &info->hardware_id, "");
+       init_unistr( &info->provider, "");
+}
+
+/********************************************************************
+ * construct_printer_info_6
+ * fill a printer_info_6 struct
+ ********************************************************************/
+static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
+{      
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       NT_PRINTER_DRIVER_INFO_LEVEL driver;
+       uint32 status=0;
+       ZERO_STRUCT(driver);
+
+       status=get_a_printer(&printer, 2, lp_servicename(snum) );
+       DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
+       if (status != 0)
+               return ERROR_INVALID_PRINTER_NAME;
+
+       status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);    
+       DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
+       if (status != 0) {
+               free_a_printer(&printer,2);
+               return ERROR_UNKNOWN_PRINTER_DRIVER;
+       }
+
+       fill_printer_driver_info_6(info, driver, servername);
+
+       free_a_printer(&printer,2);
+
+       return NT_STATUS_NO_PROBLEMO;
+}
+
 /****************************************************************************
 ****************************************************************************/
 
@@ -2705,6 +2797,15 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
        safe_free(info->dependentfiles);
 }
 
+/****************************************************************************
+****************************************************************************/
+
+static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
+{
+       safe_free(info->dependentfiles);
+       
+}
+
 /****************************************************************************
 ****************************************************************************/
 static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
@@ -2810,6 +2911,39 @@ static uint32 getprinterdriver2_level3(fstring servername, fstring architecture,
                return NT_STATUS_NO_PROBLEMO;
 }
 
+/****************************************************************************
+****************************************************************************/
+static uint32 getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+       DRIVER_INFO_6 info;
+       uint32 status;
+
+       ZERO_STRUCT(info);
+
+       status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
+       if (status != NT_STATUS_NO_PROBLEMO) {
+               return status;
+       }
+
+       /* check the required size. */  
+       *needed += spoolss_size_printer_driver_info_6(&info);
+
+       if (!alloc_buffer_size(buffer, *needed)) {
+               free_printer_driver_info_3(&info);
+               return ERROR_INSUFFICIENT_BUFFER;
+       }
+
+       /* fill the buffer with the structures */
+       new_smb_io_printer_driver_info_6("", buffer, &info, 0);
+
+       free_printer_driver_info_6(&info);
+
+       if (*needed > offered)
+               return ERROR_INSUFFICIENT_BUFFER;
+       else
+               return NT_STATUS_NO_PROBLEMO;
+}
+
 /****************************************************************************
 ****************************************************************************/
 uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, 
@@ -2843,6 +2977,9 @@ uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, u
        case 3:
                return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
                break;                          
+       case 6:
+               return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+               break;                          
        default:
                return ERROR_INVALID_LEVEL;
                break;
@@ -3678,9 +3815,13 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
                }
 
                for (i=0; i<ndrivers; i++) {
+                       uint32 status;
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
                        ZERO_STRUCT(driver);
-                       get_a_printer_driver(&driver, 3, list[i], architecture, version);
+                       if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
+                               safe_free(list);
+                               return status;
+                       }
                        fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );             
                        free_a_printer_driver(driver, 3);
                }       
@@ -3749,9 +3890,14 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
                }
                
                for (i=0; i<ndrivers; i++) {
+                       uint32 status;
+
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
                        ZERO_STRUCT(driver);
-                       get_a_printer_driver(&driver, 3, list[i], architecture, version);
+                       if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
+                               safe_free(list);
+                               return status;
+                       }
                        fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);            
                        free_a_printer_driver(driver, 3);
                }       
@@ -3820,9 +3966,14 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
                }
 
                for (i=0; i<ndrivers; i++) {
+                       uint32 status;
+
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
                        ZERO_STRUCT(driver);
-                       get_a_printer_driver(&driver, 3, list[i], architecture, version);
+                       if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
+                               safe_free(list);
+                               return status;
+                       }
                        fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);            
                        free_a_printer_driver(driver, 3);
                }       
@@ -4538,6 +4689,7 @@ uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
        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.
@@ -4552,6 +4704,7 @@ uint32 _spoolss_enumprinterdata(POLICY_HND *handle, uint32 idx,
                        free_a_printer(&printer, 2);
                        return ERROR_NO_MORE_ITEMS;
                }
+#endif
 
                safe_free(data);
                data = NULL;