r8066: * had to modify the printer data storage slightly in ntprinters.tdb
authorGerald Carter <jerry@samba.org>
Sat, 2 Jul 2005 01:23:21 +0000 (01:23 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:58:10 +0000 (10:58 -0500)
  when packing values.  It is a compatible change though and will
  not require a tdb version upgrade
* Can successfully create new printer subkeys via winreg that
  are immediately available via spoolss calls.  Still cannot delete
  keys yet though.  That comes next.
(This used to be commit 00bce2b3bb78a44842a258b1737076281297d247)

source3/printing/nt_printing.c
source3/registry/reg_printing.c
source3/rpc_server/srv_spoolss_nt.c

index dc74f885226fcfdcb0b910f6b4d1a5a82c1a29aa..47e0af963344d7e7ed57e89f4206fbb85652cd50 100644 (file)
@@ -2125,8 +2125,17 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
        for ( i=0; i<data->num_keys; i++ ) {    
                val_ctr = &data->keys[i].values;
                num_values = regval_ctr_numvals( val_ctr );
+
+               /* pack the keyname followed by a empty value */
+
+               len += tdb_pack(buf+len, buflen-len, "pPdB", 
+                               &data->keys[i].name,
+                               data->keys[i].name, 
+                               REG_NONE,
+                               0,
+                               NULL);
                
-               /* loop over all values */
+               /* now loop over all values */
                
                for ( j=0; j<num_values; j++ ) {
                        /* pathname should be stored as <key>\<value> */
@@ -2520,7 +2529,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
  Allocate and initialize a new slot.
 ***************************************************************************/
  
-static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
+int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 {
        NT_PRINTER_KEY  *d;
        int             key_index;
@@ -2530,9 +2539,12 @@ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
        
        /* allocate another slot in the NT_PRINTER_KEY array */
        
-       d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1);
-       if ( d )
-               data->keys = d;
+       if ( !(d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
+               DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
+               return -1;
+       }
+
+       data->keys = d;
        
        key_index = data->num_keys;
        
@@ -2579,7 +2591,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
 /****************************************************************************
  ***************************************************************************/
 
-uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
+int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
 {
        int     i, j;
        int     key_len;
@@ -2590,14 +2602,42 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
        
        if ( !data )
                return 0;
+
+       if ( !key )
+               return -1;
+
+       /* special case of asking for the top level printer data registry key names */
+
+       if ( strlen(key) == 0 ) {
+               for ( i=0; i<data->num_keys; i++ ) {
+               
+                       /* found a match, so allocate space and copy the name */
+                       
+                       if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
+                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
+                                       num_subkeys+1));
+                               SAFE_FREE( subkeys );
+                               return -1;
+                       }
+                       
+                       subkeys_ptr = ptr;
+                       fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
+                       num_subkeys++;
+               }
+
+               goto done;
+       }
                
+       /* asking for the subkeys of some key */
+       /* subkey paths are stored in the key name using '\' as the delimiter */
+
        for ( i=0; i<data->num_keys; i++ ) {
                if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
-                       /* match sure it is a subkey and not the key itself */
                        
+                       /* if we found the exact key, then break */
                        key_len = strlen( key );
                        if ( strlen(data->keys[i].name) == key_len )
-                               continue;
+                               break;
                        
                        /* get subkey path */
 
@@ -2634,7 +2674,13 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
                
        }
        
-       /* tag of the end */
+       /* return error if the key was not found */
+       
+       if ( i == data->num_keys )
+               return -1;
+       
+done:
+       /* tag off the end */
        
        if (num_subkeys)
                fstrcpy(subkeys_ptr[num_subkeys], "" );
@@ -3275,6 +3321,15 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
                                  &type,
                                  &size,
                                  &data_p);
+
+               /* lookup for subkey names which have a type of REG_NONE */
+               /* there's no data with this entry */
+
+               if ( type == REG_NONE ) {
+                       if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
+                               add_new_printer_key( printer_data, string );
+                       continue;
+               }
        
                /*
                 * break of the keyname from the value name.  
index f5562fcf5d86254a3519624a6b02ddf9c71adae8..09a0dd0c34698a7d973c9296839876c20c8fbe4f 100644 (file)
@@ -215,7 +215,7 @@ static char* strip_printers_prefix( const char *key )
 /*********************************************************************
  *********************************************************************/
  
-static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
        int n_services = lp_numservices();      
        int snum;
@@ -223,11 +223,11 @@ static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
        int i;
        int num_subkeys = 0;
        char *printers_key;
-       char *base, *new_path;
+       char *printername, *printerdatakey;
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        fstring *subkey_names = NULL;
        
-       DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" ));
+       DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" ));
        
        printers_key = strip_printers_prefix( key );    
        
@@ -254,12 +254,12 @@ static int key_printer_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
 
        /* get information for a specific printer */
        
-       reg_split_path( printers_key, &base, &new_path );
+       reg_split_path( printers_key, &printername, &printerdatakey );
 
-               if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) )
+       if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
                goto done;
 
-       num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names );
+       num_subkeys = get_printer_subkeys( &printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
        
        for ( i=0; i<num_subkeys; i++ )
                regsubkey_ctr_addkey( subkeys, subkey_names[i] );
@@ -277,18 +277,59 @@ done:
 /**********************************************************************
  *********************************************************************/
 
-static BOOL key_printer_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static BOOL add_printers_by_registry( REGSUBKEY_CTR *subkeys )
+{
+       return False;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
 {
        char *printers_key;
+       char *printername, *printerdatakey;
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       int i, num_subkeys;
+       char *subkeyname;
        
        printers_key = strip_printers_prefix( key );
        
        if ( !printers_key ) {
                /* have to deal with some new or deleted printer */
+               return add_printers_by_registry( subkeys );
+       }
+       
+       reg_split_path( printers_key, &printername, &printerdatakey );
+       
+       /* lookup the printer */
+       
+       if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) {
+               DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n", 
+                       printername));
                return False;
        }
 
-       return False;
+       num_subkeys = regsubkey_ctr_numkeys( subkeys );
+       for ( i=0; i<num_subkeys; i++ ) {
+               subkeyname = regsubkey_ctr_specific_key(subkeys, i);
+               /* add any missing printer keys */
+               if ( lookup_printerkey(&printer->info_2->data, subkeyname) == -1 ) {
+                       if ( add_new_printer_key( &printer->info_2->data, subkeyname ) == -1 ) 
+                               return False;
+               }
+       }
+       
+       /* write back to disk */
+       
+       mod_a_printer( printer, 2 );
+       
+       /* cleanup */
+       
+       if ( printer )
+               free_a_printer( &printer, 2 );
+
+       return True;
 }
 
 /**********************************************************************
@@ -386,7 +427,7 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
 /**********************************************************************
  *********************************************************************/
 
-static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
+static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
 {
        int             num_values;
        char            *printers_key;
@@ -420,7 +461,7 @@ static int key_printer_fetch_values( const char *key, REGVAL_CTR *values )
        p_data = &printer->info_2->data;
        if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1  ) {
                /* failure....should never happen if the client has a valid open handle first */
-               DEBUG(10,("key_printer_fetch_values: Unknown keyname [%s]\n", printerdatakey));
+               DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey));
                if ( printer )
                        free_a_printer( &printer, 2 );
                return -1;
@@ -441,7 +482,7 @@ done:
 /**********************************************************************
  *********************************************************************/
 
-static BOOL key_printer_store_values( const char *key, REGVAL_CTR *values )
+static BOOL key_printers_store_values( const char *key, REGVAL_CTR *values )
 {
        char *printers_key;
        
@@ -827,10 +868,10 @@ static struct reg_dyn_tree print_registry[] = {
        &key_forms_fetch_values,
        NULL },
 { KEY_CONTROL_PRINTERS, 
-       &key_printer_fetch_keys,
-       &key_printer_store_keys,
-       &key_printer_fetch_values,
-       &key_printer_store_values },
+       &key_printers_fetch_keys,
+       &key_printers_store_keys,
+       &key_printers_fetch_values,
+       &key_printers_store_values },
 { KEY_ENVIRONMENTS,
        &key_driver_fetch_keys,
        NULL,
@@ -842,10 +883,10 @@ static struct reg_dyn_tree print_registry[] = {
        NULL,
        NULL },
 { KEY_WINNT_PRINTERS,
-       &key_printer_fetch_keys,
-       &key_printer_store_keys,
-       &key_printer_fetch_values,
-       &key_printer_store_values },
+       &key_printers_fetch_keys,
+       &key_printers_store_keys,
+       &key_printers_fetch_values,
+       &key_printers_store_values },
 { KEY_PORTS,
        &regdb_fetch_keys, 
        &regdb_store_keys,
index 12e8e2bd414f9f3a016ecc667608d540e442bb8d..19ef3700e6dbc3ef938ba2858185916d959f7d71 100644 (file)
@@ -583,7 +583,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
                
                DEBUGADD(10, ("printername: %s\n", printername));
                
-                       free_a_printer( &printer, 2);
+               free_a_printer( &printer, 2);
        }
 
        if ( !found ) {