r36: - Start using memory pools in the registry library
authorJelmer Vernooij <jelmer@samba.org>
Mon, 5 Apr 2004 10:28:59 +0000 (10:28 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:50:40 +0000 (12:50 -0500)
- Remove obsolete file
(This used to be commit d85b8fb3b74b236fb03cf0931a0f585eec74536a)

source4/lib/registry/common/reg_display.c [deleted file]
source4/lib/registry/common/reg_interface.c
source4/lib/registry/common/reg_objects.c
source4/lib/registry/common/reg_util.c
source4/lib/registry/common/registry.h
source4/lib/registry/reg_backend_dir/reg_backend_dir.c
source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c

diff --git a/source4/lib/registry/common/reg_display.c b/source4/lib/registry/common/reg_display.c
deleted file mode 100644 (file)
index e12f4ba..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   Copyright (C) Gerald Carter                     2001
-   Copyright (C) Tim Potter                        2000
-   Copyright (C) Jelmer Vernooij                                  2004
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-void display_reg_value(REG_VAL *value)
-{
-       pstring text;
-
-       switch(reg_val_type(value)) {
-       case REG_DWORD:
-               printf("%s: REG_DWORD: 0x%08x\n", reg_val_name(value), 
-                      *((uint32 *) reg_val_data_blk(value)));
-               break;
-       case REG_SZ:
-               rpcstr_pull(text, reg_val_data_blk(value), sizeof(text), reg_val_size(value),
-                           STR_TERMINATE);
-               printf("%s: REG_SZ: %s\n", reg_val_name(value), text);
-               break;
-       case REG_BINARY:
-               printf("%s: REG_BINARY: unknown length value not displayed\n",
-                      reg_val_name(value));
-               break;
-       case REG_MULTI_SZ: {
-               uint16 *curstr = (uint16 *) reg_val_data_blk(value);
-               uint8 *start = reg_val_data_blk(value);
-               printf("%s: REG_MULTI_SZ:\n", reg_val_name(value));
-               while ((*curstr != 0) && 
-                      ((uint8 *) curstr < start + reg_val_size(value))) {
-                       rpcstr_pull(text, curstr, sizeof(text), -1, 
-                                   STR_TERMINATE);
-                       printf("  %s\n", text);
-                       curstr += strlen(text) + 1;
-               }
-       }
-       break;
-       default:
-               printf("%s: unknown type %d\n", reg_val_name(value), reg_val_type(value));
-       }
-       
-}
index d40a855f898658e7bb553f209ff37e116d51b0c5..b6b38e9b62cc71002b0f9320e05bfe6f12a1813b 100644 (file)
@@ -55,7 +55,6 @@ NTSTATUS registry_register(void *_function)
        return NT_STATUS_OK;
 }
 
-
 /* Find a backend in the list of available backends */
 static struct reg_init_function_entry *reg_find_backend_entry(const char *name)
 {
@@ -74,6 +73,7 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
 {
        struct reg_init_function_entry *entry;
        static BOOL reg_first_init = True;
+       TALLOC_CTX *mem_ctx;
        REG_HANDLE *ret;
 
        if(reg_first_init) {
@@ -91,12 +91,14 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
                DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
                return NULL;
        }
-
-       ret = malloc(sizeof(REG_HANDLE));
+       
+       mem_ctx = talloc_init(backend);
+       ret = talloc(mem_ctx, sizeof(REG_HANDLE));
        ZERO_STRUCTP(ret);      
-       ret->location = location?strdup(location):NULL;
+       ret->location = location?talloc_strdup(mem_ctx, location):NULL;
        ret->functions = entry->functions;
        ret->backend_data = NULL;
+       ret->mem_ctx = mem_ctx;
 
        if(!entry->functions->open_registry) {
                return ret;
@@ -105,15 +107,19 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
        if(entry->functions->open_registry(ret, location, try_full_load))
                return ret;
 
-       SAFE_FREE(ret);
+       talloc_destroy(mem_ctx);
        return NULL;
 }
 
-/* Open a key */
+/* Open a key 
+ * First tries to use the open_key function from the backend
+ * then falls back to get_subkey_by_name and later get_subkey_by_index 
+ */
 REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
 {
        char *fullname;
        REG_KEY *ret = NULL;
+       TALLOC_CTX *mem_ctx;
 
        if(!parent) {
                DEBUG(0, ("Invalid parent key specified"));
@@ -131,16 +137,23 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
                while(curbegin && *curbegin) {
                        if(curend)*curend = '\0';
                        curkey = reg_key_get_subkey_by_name(curkey, curbegin);
-                       if(!curkey) return NULL;
+                       if(!curkey) {
+                               SAFE_FREE(orig);
+                               return NULL;
+                       }
                        if(!curend) break;
                        curbegin = curend + 1;
                        curend = strchr(curbegin, '\\');
                }
+               SAFE_FREE(orig);
                
                return curkey;
        }
 
-       asprintf(&fullname, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name);
+       mem_ctx = talloc_init("mem_ctx");
+
+       fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name);
+
 
        if(!parent->handle->functions->open_key) {
                DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n"));
@@ -152,8 +165,10 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
        if(ret) {
                ret->handle = parent->handle;
                ret->path = fullname;
-       } else
-               SAFE_FREE(fullname);
+               talloc_steal(mem_ctx, ret->mem_ctx, fullname);
+       }
+
+       talloc_destroy(mem_ctx);
 
        return ret;
 }
@@ -241,7 +256,7 @@ REG_KEY *reg_key_get_subkey_by_index(REG_KEY *key, int idx)
        }
 
        if(ret && !ret->path) {
-               asprintf(&ret->path, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
+               ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
                ret->handle = key->handle;
        }
 
@@ -270,7 +285,7 @@ REG_KEY *reg_key_get_subkey_by_name(REG_KEY *key, const char *name)
        }
 
        if(ret && !ret->path) {
-               asprintf(&ret->path, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
+               ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
                ret->handle = key->handle;
        }
                
@@ -310,7 +325,9 @@ BOOL reg_key_del(REG_KEY *key)
 {
        if(key->handle->functions->del_key) {
                if(key->handle->functions->del_key(key)) {
-                       free_cached_keys(key);          
+                       /* Invalidate cache */
+                       key->cache_subkeys = NULL;
+                       key->cache_subkeys_count = 0;
                        return True;
                }
        }
@@ -356,7 +373,8 @@ BOOL reg_val_del(REG_VAL *val)
        }
        
        if(val->handle->functions->del_value(val)) {
-               free_cached_values(val->parent);
+               val->parent->cache_values = NULL;
+               val->parent->cache_values_count = 0;
                return True;
        } 
        return False;
@@ -398,7 +416,8 @@ BOOL reg_key_add_name(REG_KEY *parent, const char *name)
        }
 
        if(parent->handle->functions->add_key(parent, name)) {
-               free_cached_keys(parent);
+               parent->cache_subkeys = NULL;
+               parent->cache_subkeys_count = 0;
                return True;
        } 
        return False;
@@ -419,7 +438,8 @@ BOOL reg_val_update(REG_VAL *val, int type, void *data, int len)
                
                new = val->handle->functions->add_value(val->parent, val->name, type, data, len);
                memcpy(val, new, sizeof(REG_VAL));
-               free_cached_values(val->parent);
+               val->parent->cache_values = NULL;
+               val->parent->cache_values_count = 0;
                return True;
        }
                
@@ -447,7 +467,7 @@ REG_KEY *reg_get_root(REG_HANDLE *h)
 
        if(ret) {
                ret->handle = h;
-               ret->path = strdup("\\");
+               ret->path = talloc_strdup(ret->mem_ctx, "\\");
        }
 
        return ret;
@@ -462,19 +482,9 @@ REG_VAL *reg_key_add_value(REG_KEY *key, const char *name, int type, void *value
        ret = key->handle->functions->add_value(key, name, type, value, vallen);
        ret->parent = key;
        ret->handle = key->handle;
-       free_cached_values(key);
-       return ret;
-}
 
-void free_cached_values(REG_KEY *key) 
-{
-       free(key->cache_values); key->cache_values = NULL;
+       /* Invalidate the cache */
+       key->cache_values = NULL;
        key->cache_values_count = 0;
-}
-
-
-void free_cached_keys(REG_KEY *key) 
-{
-       free(key->cache_subkeys); key->cache_subkeys = NULL;
-       key->cache_subkeys_count = 0;
+       return ret;
 }
index 8de0065da01b8fb1ac81d405117f5a451b58aa5d..809829b3e8fa17ced3d15db694c8e9b21573270f 100644 (file)
 REG_VAL* reg_val_dup( REG_VAL *val )
 {
        REG_VAL         *copy = NULL;
+       TALLOC_CTX *new_mem_ctx = talloc_init(val->name);
        
        if ( !val ) 
                return NULL;
        
-       if ( !(copy = malloc( sizeof(REG_VAL) )) ) {
+       if ( !(copy = talloc( new_mem_ctx, sizeof(REG_VAL) )) ) {
                DEBUG(0,("dup_registry_value: malloc() failed!\n"));
                return NULL;
        }
@@ -49,12 +50,13 @@ REG_VAL* reg_val_dup( REG_VAL *val )
        memcpy( copy, val, sizeof(REG_VAL) );
        if ( val->data_blk ) 
        {
-               if ( !(copy->data_blk = memdup( val->data_blk, val->data_len )) ) {
+               if ( !(copy->data_blk = talloc_memdup( new_mem_ctx, val->data_blk, val->data_len )) ) {
                        DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
                                val->data_len));
                        SAFE_FREE( copy );
                }
        }
+       copy->mem_ctx = new_mem_ctx;
        
        return copy;    
 }
@@ -71,8 +73,7 @@ void reg_val_free( REG_VAL *val )
        if(val->handle->functions->free_val_backend_data)
                val->handle->functions->free_val_backend_data(val);
                
-       SAFE_FREE( val->data_blk );
-       SAFE_FREE( val );
+       talloc_destroy( val->mem_ctx );
 
        return;
 }
@@ -139,7 +140,6 @@ void reg_key_free(REG_KEY *key)
                for(i = 0; i < key->cache_values_count; i++) {
                        reg_val_free(key->cache_values[i]);
                }
-               SAFE_FREE(key->cache_values);
        }
 
        if(key->cache_subkeys) {
@@ -147,12 +147,9 @@ void reg_key_free(REG_KEY *key)
                for(i = 0; i < key->cache_subkeys_count; i++) {
                        reg_key_free(key->cache_subkeys[i]);
                }
-               SAFE_FREE(key->cache_subkeys);
        }
 
-       SAFE_FREE(key->path);
-       SAFE_FREE(key->name);
-       SAFE_FREE(key);
+       talloc_destroy(key->mem_ctx);
 }
 
 char *reg_val_get_path(REG_VAL *v)
@@ -170,11 +167,14 @@ const char *reg_key_get_path(REG_KEY *k)
 /* For use by the backends _ONLY_ */
 REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data)
 {
-       REG_KEY *r = malloc(sizeof(REG_KEY));
+       REG_KEY *r;
+       TALLOC_CTX *mem_ctx = talloc_init(path);
+       r = talloc(mem_ctx, sizeof(REG_KEY));
        ZERO_STRUCTP(r);
        r->handle = h;
-       r->path = strdup(path);
-       r->name = strdup(strrchr(path, '\\')?strrchr(path,'\\')+1:path);
+       r->mem_ctx = mem_ctx;
+       r->path = talloc_strdup(mem_ctx, path);
+       r->name = talloc_strdup(mem_ctx, strrchr(path, '\\')?strrchr(path,'\\')+1:path);
        r->backend_data = data;
        r->ref = 1;
        return r;
@@ -182,19 +182,25 @@ REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data)
 
 REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data)
 {
-       REG_KEY *r = malloc(sizeof(REG_KEY));
+       REG_KEY *r;
+       TALLOC_CTX *mem_ctx = talloc_init(name);
+       r = talloc(mem_ctx, sizeof(REG_KEY));
        ZERO_STRUCTP(r);
        r->handle = k->handle;
-       r->name = strdup(name);
+       r->name = talloc_strdup(mem_ctx, name);
        r->backend_data = data;
+       r->mem_ctx = mem_ctx;
        r->ref = 1;
        return r;
 }
 
 REG_VAL *reg_val_new(REG_KEY *parent, void *data)
 {
-       REG_VAL *r = malloc(sizeof(REG_VAL));
+       REG_VAL *r;
+       TALLOC_CTX *mem_ctx = talloc_init("value");
+       r = talloc(mem_ctx, sizeof(REG_VAL));
        ZERO_STRUCTP(r);
+       r->mem_ctx = mem_ctx;
        r->handle = parent->handle;
        r->backend_data = data;
        r->ref = 1;
index 2941c38cf4360925488e29e8e477a1b8113379b4..060d053fc27aeacaae4670de61295585f9924a0c 100644 (file)
@@ -82,7 +82,7 @@ char *reg_val_data_string(REG_VAL *v)
   return ret;
 }
 
-const char *reg_val_description(REG_VAL *val) 
+char *reg_val_description(REG_VAL *val) 
 {
        char *ret, *ds = reg_val_data_string(val);
        asprintf(&ret, "%s = %s : %s", reg_val_name(val)?reg_val_name(val):"<No Name>", str_regtype(reg_val_type(val)), ds);
@@ -145,6 +145,9 @@ BOOL reg_split_path( char *path, char **base, char **new_path )
        return True;
 }
 
+/**
+ * Replace all \'s with /'s
+ */
 char *reg_path_win2unix(char *path) 
 {
        int i;
@@ -153,7 +156,9 @@ char *reg_path_win2unix(char *path)
        }
        return path;
 }
-
+/**
+ * Replace all /'s with \'s
+ */
 char *reg_path_unix2win(char *path) 
 {
        int i;
index 4b2900621740e4572e06c93a46ea0239b6184389..3565a7a5851e08749b5df2ffb80d1c8ad4aa1bf3 100644 (file)
@@ -40,6 +40,7 @@ struct reg_key_s {
   int cache_values_count;
   REG_KEY **cache_subkeys; 
   int cache_subkeys_count;
+  TALLOC_CTX *mem_ctx;
   int ref;
 };
 
@@ -52,6 +53,7 @@ struct reg_val_s {
   REG_HANDLE *handle;
   REG_KEY *parent;
   void *backend_data;
+  TALLOC_CTX *mem_ctx;
   int ref;
 };
 
@@ -107,6 +109,7 @@ struct reg_handle_s {
        REG_SUBTREE *subtrees;
        char *location;
        void *backend_data;
+       TALLOC_CTX *mem_ctx;
 };
 
 struct reg_init_function_entry {
index 5fec782e95fca7e90ab7ee0ca8aa3c022dbd9cac..9cb15cd28581d72ad47bbf064f4f793b9858476e 100644 (file)
@@ -28,7 +28,7 @@ static BOOL reg_dir_add_key(REG_KEY *parent, const char *name)
        asprintf(&path, "%s%s\\%s", parent->handle->location, reg_key_get_path(parent), name);
        path = reg_path_win2unix(path);
        ret = mkdir(path, 0700);
-       free(path);
+       SAFE_FREE(path);
        return (ret == 0);
 }
 
@@ -41,22 +41,26 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
 {
        DIR *d;
        char *fullpath;
+       REG_KEY *ret;
+       TALLOC_CTX *mem_ctx = talloc_init("tmp");
        if(!name) {
                DEBUG(0, ("NULL pointer passed as directory name!"));
                return NULL;
        }
-       asprintf(&fullpath, "%s%s", h->location, name);
+       fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name);
        fullpath = reg_path_win2unix(fullpath);
        
        d = opendir(fullpath);
        if(!d) {
                DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno)));
-               SAFE_FREE(fullpath);
+               talloc_destroy(mem_ctx);
                return NULL;
        }
        closedir(d);
-       
-       return reg_key_new_abs(name, h, fullpath);
+       ret = reg_key_new_abs(name, h, fullpath);
+       talloc_steal(mem_ctx, ret->mem_ctx, fullpath);
+       talloc_destroy(mem_ctx);
+       return ret;
 }
 
 static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
@@ -67,7 +71,7 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
        REG_KEY **ar;
        DIR *d;
        (*count) = 0;
-       ar = malloc(sizeof(REG_KEY *) * max);
+       ar = talloc(k->mem_ctx, sizeof(REG_KEY *) * max);
 
        d = opendir(fullpath);
 
@@ -78,8 +82,8 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
                   strcmp(e->d_name, ".") &&
                   strcmp(e->d_name, "..")) {
                        char *newfullpath;
-                       asprintf(&newfullpath, "%s/%s", fullpath, e->d_name);
-                       ar[(*count)] = reg_key_new_rel(e->d_name, k, newfullpath);
+                       ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL);
+                       ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name);
                        if(ar[(*count)])(*count)++;
 
                        if((*count) == max) {
@@ -100,17 +104,12 @@ static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) {
        return True;
 }
 
-static void dir_free(REG_KEY *k) 
-{
-       free(k->backend_data);
-}
-
 static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
 {
        REG_VAL *ret = reg_val_new(p, NULL);
        char *fullpath;
        FILE *fd;
-       ret->name = name?strdup(name):NULL;
+       ret->name = name?talloc_strdup(ret->mem_ctx, name):NULL;
        fullpath = reg_path_win2unix(strdup(reg_val_get_path(ret)));
        
        fd = fopen(fullpath, "w+");
@@ -134,7 +133,6 @@ static REG_OPS reg_backend_dir = {
        .del_key = reg_dir_del_key,
        .add_value = reg_dir_add_value,
        .del_value = reg_dir_del_value,
-       .free_key_backend_data = dir_free
 };
 
 NTSTATUS reg_dir_init(void)
index 14da2f54e99d4f436baf72027c4ec19a2ab1e193..71d3361ce26cfd5d03266cb10e09bada79dc50dd 100644 (file)
@@ -35,34 +35,35 @@ static BOOL reg_close_gconf(REG_HANDLE *h)
 
 static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name) 
 {
+       REG_KEY *ret;
        char *fullpath = reg_path_win2unix(strdup(name));
 
        /* Check if key exists */
        if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) {
-               free(fullpath);
+               SAFE_FREE(fullpath);
                return NULL;
        }
-       free(fullpath);
+       ret = reg_key_new_abs(name, h, NULL);
+       ret->backend_data = talloc_strdup(ret->mem_ctx, fullpath);
+       SAFE_FREE(fullpath);
 
-       return reg_key_new_abs(name, h, NULL);
+       return ret;
 }
 
 static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
 {
        GSList *entries;
        GSList *cur;
-       REG_VAL **ar = malloc(sizeof(REG_VAL *));
-       char *fullpath = strdup(reg_key_get_path(p));
-       fullpath = reg_path_win2unix(fullpath);
+       REG_VAL **ar = talloc(p->mem_ctx, sizeof(REG_VAL *));
+       char *fullpath = p->backend_data;
        cur = entries = gconf_client_all_entries((GConfClient*)p->handle->backend_data, fullpath, NULL);
-       free(fullpath);
 
        (*count) = 0;
        while(cur) {
                GConfEntry *entry = cur->data;
                GConfValue *value = gconf_entry_get_value(entry);
                REG_VAL *newval = reg_val_new(p, NULL);
-               newval->name = strdup(strrchr(gconf_entry_get_key(entry), '/')+1);
+               newval->name = talloc_strdup(newval->mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1);
                if(value) {
                        switch(value->type) {
                        case GCONF_VALUE_INVALID: 
@@ -71,26 +72,26 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
 
                        case GCONF_VALUE_STRING:
                                newval->data_type = REG_SZ;
-                               newval->data_blk = strdup(gconf_value_get_string(value));
+                               newval->data_blk = talloc_strdup(newval->mem_ctx, gconf_value_get_string(value));
                                newval->data_len = strlen(newval->data_blk);
                                break;
 
                        case GCONF_VALUE_INT:
                                newval->data_type = REG_DWORD;
-                               newval->data_blk = malloc(sizeof(long));
+                               newval->data_blk = talloc(newval->mem_ctx, sizeof(long));
                                *((long *)newval->data_blk) = gconf_value_get_int(value);
                                newval->data_len = sizeof(long);
                                break;
 
                        case GCONF_VALUE_FLOAT:
-                               newval->data_blk = malloc(sizeof(double));
+                               newval->data_blk = talloc(newval->mem_ctx, sizeof(double));
                                newval->data_type = REG_BINARY;
                                *((double *)newval->data_blk) = gconf_value_get_float(value);
                                newval->data_len = sizeof(double);
                                break;
 
                        case GCONF_VALUE_BOOL:
-                               newval->data_blk = malloc(sizeof(BOOL));
+                               newval->data_blk = talloc(newval->mem_ctx, sizeof(BOOL));
                                newval->data_type = REG_BINARY;
                                *((BOOL *)newval->data_blk) = gconf_value_get_bool(value);
                                newval->data_len = sizeof(BOOL);
@@ -104,7 +105,7 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
                } else newval->data_type = REG_NONE; 
 
                ar[(*count)] = newval;
-               ar = realloc(ar, sizeof(REG_VAL *) * ((*count)+2));
+               ar = talloc_realloc(p->mem_ctx, ar, sizeof(REG_VAL *) * ((*count)+2));
                (*count)++;
                g_free(cur->data);
                cur = cur->next;
@@ -120,14 +121,13 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
        GSList *dirs;
        GSList *cur;
        REG_KEY **ar = malloc(sizeof(REG_KEY *));
-       char *fullpath = strdup(reg_key_get_path(p));
-       fullpath = reg_path_win2unix(fullpath);
+       char *fullpath = p->backend_data;
        cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL);
-       free(fullpath);
 
        (*count) = 0;
        while(cur) {
-               ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle, NULL);
+               ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle,NULL);
+               ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, cur->data);
                ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+2));
                (*count)++;
                g_free(cur->data);
@@ -142,11 +142,10 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
 static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len)
 {
        GError *error = NULL;
-       char *keypath = reg_path_win2unix(strdup(reg_key_get_path(val->parent)));
+       char *keypath = val->backend_data;
        char *valpath;
        if(val->name)asprintf(&valpath, "%s/%s", keypath, val->name);
        else valpath = strdup(keypath);
-       free(keypath);
        
        switch(type) {
        case REG_SZ: