fix to allow EnumPrinterKey() to enumerate multiple levels of subkeys.
authorGerald Carter <jerry@samba.org>
Sun, 18 Aug 2002 11:11:48 +0000 (11:11 +0000)
committerGerald Carter <jerry@samba.org>
Sun, 18 Aug 2002 11:11:48 +0000 (11:11 +0000)
Works on the top level.  Needs more testing for levels > 1.

source/printing/nt_printing.c
source/registry/reg_frontend.c
source/rpc_server/srv_spoolss_nt.c

index 3b85fce0200beba4cdf70d5f0ed767c28ff8dea9..d51d3bc1bbced505efa3311f64a1998b13554ad6 100644 (file)
@@ -2407,7 +2407,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, char *name )
        
        for ( i=0; i<data->num_keys; i++ ) 
        {
-               if ( strcmp(data->keys[i].name, name) == 0 ) {
+               if ( strequal(data->keys[i].name, name) ) {
                        DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
                        key_index = i;
                        break;
@@ -2418,6 +2418,66 @@ int lookup_printerkey( NT_PRINTER_DATA *data, char *name )
        return key_index;
 }
 
+/****************************************************************************
+ ***************************************************************************/
+
+uint32 get_printer_subkeys( NT_PRINTER_DATA *data, char* key, fstring **subkeys )
+{
+       int     i;
+       int     key_len;
+       int     num_subkeys = 0;
+       char    *p;
+       fstring *ptr, *subkeys_ptr = NULL;
+       
+       if ( !data )
+               return 0;
+               
+       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 */
+                       
+                       key_len = strlen( key );
+                       if ( strlen(data->keys[i].name) == key_len )
+                               continue;
+                       
+                       /* get subkey path */
+
+                       p = data->keys[i].name + key_len;
+                       
+                       /* found a match, so allocate space and copy the name */
+                       
+                       if ( !(ptr = Realloc( subkeys_ptr, (num_subkeys+2)*sizeof(fstring))) ) {
+                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
+                                       num_subkeys+1));
+                               SAFE_FREE( subkeys );
+                               return 0;
+                       }
+                       
+                       subkeys_ptr = ptr;
+                       
+                       /* copy the subkey name and trim off any trailing 
+                          subkeys below it */
+                          
+                       fstrcpy( subkeys_ptr[num_subkeys], p );
+                       p = strchr( subkeys_ptr[num_subkeys], '\\' );
+                       if ( p )
+                               *p = '\0';
+                       num_subkeys++;
+               }
+               
+       }
+       
+       /* tag of the end */
+       
+       fstrcpy( subkeys_ptr[num_subkeys], "" );
+       
+       *subkeys = subkeys_ptr;
+
+       return num_subkeys;
+}
 /****************************************************************************
  ***************************************************************************/
  
@@ -2465,11 +2525,8 @@ WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value
 
        key_index = lookup_printerkey( &p2->data, key );
        if ( key_index == -1 )
-               key_index = add_new_printer_key( &p2->data, key );
+               return WERR_OK;
                
-       if ( key_index == -1 )
-               return WERR_NOMEM;
-       
        regval_ctr_delvalue( &p2->data.keys[key_index].values, value );
        
        DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
index 45c1f24001070d10e1eab1db0606613eccff0260..994f03cf5ac97b4ac36b82f2cbdfebae58935cf9 100644 (file)
@@ -332,9 +332,8 @@ REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, char *name )
        /* search for the value */
        
        for ( i=0; i<ctr->num_values; i++ ) {
-               if ( strcmp( ctr->values[i]->valuename, name ) == 0)
+               if ( strequal( ctr->values[i]->valuename, name ) == 0)
                        return ctr->values[i];
-               
        }
        
        return NULL;
index cbafe982be4d9ec6cd6d3f32716976e6dac06028..7286fef5283a4ec9bb0ba93e5e53f8df8c69b02b 100644 (file)
@@ -4402,9 +4402,6 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, char *s
                                v = ""; /* hack to handle null lists */
                }
                
-               if ( !strlen(v) ) 
-                       break;
-               
                /* hack to allow this to be used in places other than when generating 
                   the list of dependent files */
                   
@@ -4421,6 +4418,9 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, char *s
                } else
                        *uni_array = tuary;
                        
+               if ( !strlen(v) ) 
+                       break;
+               
                j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
                i++;
        }
@@ -7989,16 +7989,16 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
 {
        fstring         key;
-       fstring         *keynames;
+       fstring         *keynames = NULL;
        uint16          *enumkeys = NULL;
+       int             num_keys;
        int             printerkey_len;
-       int             i;
        POLICY_HND      *handle = &q_u->handle;
        Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
        NT_PRINTER_DATA *data;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int             snum = 0;
-       WERROR          status;
+       WERROR          status = WERR_BADFILE;
        
        
        DEBUG(4,("_spoolss_enumprinterkey\n"));
@@ -8015,56 +8015,42 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO
        if (!W_ERROR_IS_OK(status))
                return status;
                
+       /* get the list of subkey names */
+       
        unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 );
+       data = &printer->info_2->data;
 
-       /* enumerating all keys if (key == "") */
+       num_keys = get_printer_subkeys( data, key, &keynames );
 
-       data = &printer->info_2->data;
-       
-       if ( !strlen( key ) )
-       {
-               keynames = talloc_zero( p->mem_ctx, (data->num_keys+1)*sizeof(fstring) );
-               
-               /* make an array of all the keynames */
-               
-               for ( i=0; i<data->num_keys; i++ )
-                       fstrcpy( keynames[i], data->keys[i].name );
-               fstrcpy( keynames[i], "" );
-               
-               printerkey_len = init_unistr_array( &enumkeys,  keynames, NULL );
-               
-               r_u->needed = printerkey_len*2;
-               
-               if ( q_u->size < r_u->needed )
-                       return WERR_MORE_DATA;
-                               
-               if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys))
-                       return WERR_BADFILE;
-                       
-               return WERR_OK;
+       if ( num_keys == -1 ) {
+               status = WERR_BADFILE;
+               goto done;
        }
-       
-       /* The "PrinterDriverData" key should have no subkeys */
-       if ( strcmp(key, SPOOL_PRINTERDATA_KEY) == 0 )
-       {
-               uint16  dummy_key = 0;
-               
-               r_u->needed = 2;
-               
-               if (q_u->size < r_u->needed)
-                       return WERR_MORE_DATA;
-                       
-               if ( !make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, &dummy_key ) )
-                       return WERR_BADFILE;
-                       
-               return WERR_OK;
+
+       printerkey_len = init_unistr_array( &enumkeys,  keynames, NULL );
+
+       r_u->needed = printerkey_len*2;
+
+       if ( q_u->size < r_u->needed ) {
+               status = WERR_MORE_DATA;
+               goto done;
        }
-       
 
-       /* The return value for an unknown key is documented in MSDN
-          EnumPrinterKey description */
-          
-        return WERR_BADFILE;
+       if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
+               status = WERR_NOMEM;
+               goto done;
+       }
+                       
+       status = WERR_OK;
+
+       if ( q_u->size < r_u->needed ) 
+               status = WERR_MORE_DATA;
+
+done:
+       free_a_printer( &printer, 2 );
+       SAFE_FREE( keynames );
+       
+        return status;
 }
 
 /********************************************************************
@@ -8126,7 +8112,6 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
                return WERR_BADFID;
        }
 
-               
        /* first get the printer off of disk */
        
        if (!get_printer_snum(p,handle, &snum))