summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/registry/reg_frontend.c57
-rw-r--r--source3/rpc_server/srv_winreg_nt.c41
2 files changed, 28 insertions, 70 deletions
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index b361359985..5a76e36c81 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -185,63 +185,6 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
}
/***********************************************************************
- 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
***********************************************************************/
diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c
index ffce49cd9c..ce3e2e4b7d 100644
--- a/source3/rpc_server/srv_winreg_nt.c
+++ b/source3/rpc_server/srv_winreg_nt.c
@@ -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;