Move the subkey cache to srv_winreg_nt.c
authorvlendec <vlendec@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Mon, 27 Nov 2006 07:41:59 +0000 (07:41 +0000)
committervlendec <vlendec@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Mon, 27 Nov 2006 07:41:59 +0000 (07:41 +0000)
git-svn-id: svn+ssh://svn.samba.org/data/svn/samba/branches/SAMBA_3_0@19912 0c0555d6-39d7-0310-84fc-f1cc0bd64818

source/registry/reg_frontend.c
source/rpc_server/srv_winreg_nt.c

index b3613599859330adf3fadfa997cd0ad63e8f567c..5a76e36c813602d73d5f14c37f1b5dba9a365cb7 100644 (file)
@@ -184,63 +184,6 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
        return result;
 }
 
-/***********************************************************************
- retreive a specific subkey specified by index.  Caller is 
- responsible for freeing memory
- ***********************************************************************/
-
-BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
-{
-       static REGSUBKEY_CTR *ctr = NULL;
-       static pstring save_path;
-       char *s;
-       
-       *subkey = NULL;
-       
-       /* simple caching for performance; very basic heuristic */
-
-       DEBUG(8,("fetch_reg_keys_specific: Looking for key [%d] of  [%s]\n", key_index, key->name));
-       
-       if ( !ctr ) {
-               DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
-
-               if ( !(ctr = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
-                       DEBUG(0,("fetch_reg_keys_specific: talloc() failed!\n"));
-                       return False;
-               }
-               
-               pstrcpy( save_path, key->name );
-               
-               if ( fetch_reg_keys( key, ctr) == -1 )
-                       return False;
-                       
-       }
-       /* clear the cache when key_index == 0 or the path has changed */
-       else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
-
-               DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
-               
-               TALLOC_FREE( ctr );
-
-               if ( !(ctr = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
-                       DEBUG(0,("fetch_reg_keys_specific: talloc() failed!\n"));
-                       return False;
-               }
-               
-               pstrcpy( save_path, key->name );
-               
-               if ( fetch_reg_keys( key, ctr) == -1 )
-                       return False;
-       }
-       
-       if ( !(s = regsubkey_ctr_specific_key( ctr, key_index )) )
-               return False;
-
-       *subkey = SMB_STRDUP( s );
-
-       return True;
-}
-
 /***********************************************************************
  High level wrapper function for enumerating registry values
  ***********************************************************************/
index ffce49cd9c339668b5f70ed42478f15233e5e78a..ce3e2e4b7d42cda2f2695f1d6377e26459ce9bf3 100644 (file)
@@ -33,6 +33,7 @@ static struct generic_mapping reg_generic_map =
 struct regkey_info {
        REGISTRY_KEY *key;
        REGVAL_CTR *value_cache;
+       REGSUBKEY_CTR *subkey_cache;
 };
 
 /******************************************************************
@@ -576,35 +577,47 @@ WERROR _winreg_GetVersion(pipes_struct *p, struct policy_handle *handle, uint32_
 WERROR _winreg_EnumKey(pipes_struct *p, struct policy_handle *handle, uint32_t enum_index, struct winreg_StringBuf *name, struct winreg_StringBuf *keyclass, NTTIME *last_changed_time)
 {
        WERROR  status = WERR_OK;
-       REGISTRY_KEY    *regkey = find_regkey_by_hnd( p, handle );
-       char            *subkey = NULL;
-       
+       struct regkey_info *info = find_regkey_info_by_hnd( p, handle );
+       REGISTRY_KEY    *regkey;
        
-       if ( !regkey )
+       if ( !info )
                return WERR_BADFID; 
 
+       regkey = info->key;
+
        if ( !name || !keyclass )
                return WERR_INVALID_PARAM;
 
        DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name));
        
-       if ( !fetch_reg_keys_specific( regkey, &subkey, enum_index ) ) {
-               status = WERR_NO_MORE_ITEMS;
-               goto done;
+       if (!info->subkey_cache) {
+               if (!(info->subkey_cache = TALLOC_ZERO_P(
+                             info, REGSUBKEY_CTR))) {
+                       return WERR_NOMEM;
        }
        
-       DEBUG(10,("_reg_enum_key: retrieved subkey named [%s]\n", subkey));
+               if (fetch_reg_keys(regkey, info->subkey_cache) == -1) {
+                       TALLOC_FREE(info->subkey_cache);
+                       return WERR_NO_MORE_ITEMS;
+               }
+       }
+
+       if (enum_index >= info->subkey_cache->num_subkeys) {
+               return WERR_NO_MORE_ITEMS;
+       }
+
+       DEBUG(10,("_reg_enum_key: retrieved subkey named [%s]\n",
+                 info->subkey_cache->subkeys[enum_index]));
        
+       if (!(name->name = talloc_strdup(
+                     p->mem_ctx, info->subkey_cache->subkeys[enum_index]))) {
+               status = WERR_NOMEM;
+       }
        if ( last_changed_time ) {
                *last_changed_time = 0;
        }
        keyclass->name = "";
-       if ( (name->name = talloc_strdup( p->mem_ctx, subkey )) == NULL ) {
-               status = WERR_NOMEM;
-       }
 
-done:  
-       SAFE_FREE( subkey );
        return status;
 }
 
@@ -1261,6 +1274,7 @@ WERROR _winreg_CreateKey( pipes_struct *p, struct policy_handle *handle,
        write_result = store_reg_keys( newparentinfo->key, subkeys );
        
        TALLOC_FREE( subkeys );
+       TALLOC_FREE( newparentinfo->subkey_cache );
 
        if ( !write_result )
                return WERR_REG_IO_FAILURE;
@@ -1419,6 +1433,7 @@ WERROR _winreg_DeleteKey(pipes_struct *p, struct policy_handle *handle, struct w
        write_result = store_reg_keys( newparentinfo->key, subkeys );
        
        TALLOC_FREE( subkeys );
+       TALLOC_FREE( newparentinfo->subkey_cache );
 
        result = write_result ? WERR_OK : WERR_REG_IO_FAILURE;