diff options
author | Chris Davis <cd.rattan@gmail.com> | 2014-06-30 23:19:53 -0700 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2014-10-01 14:32:09 +0200 |
commit | f9a2f2eb7cc3c69f20ab615dd98b750414672fe3 (patch) | |
tree | a1c7b709dfb797d44df004d166839f2c6f0db055 /source3/utils | |
parent | 41d5112407d7426d75671ac6967e62b080f63857 (diff) | |
download | samba-f9a2f2eb7cc3c69f20ab615dd98b750414672fe3.tar.gz samba-f9a2f2eb7cc3c69f20ab615dd98b750414672fe3.tar.xz samba-f9a2f2eb7cc3c69f20ab615dd98b750414672fe3.zip |
regedit: make all hives descend from a root node
This helps simplify cleanup, since each node's talloc context is the
parent node, and freeing the root node will destroy the entire tree
without any extra utility functions.
It also wouldn't be hard to extend this later on to support browsing
multiple registries at the same time.
Signed-off-by: Chris Davis <cd.rattan@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3/utils')
-rw-r--r-- | source3/utils/regedit.c | 60 | ||||
-rw-r--r-- | source3/utils/regedit_treeview.c | 90 | ||||
-rw-r--r-- | source3/utils/regedit_treeview.h | 6 |
3 files changed, 79 insertions, 77 deletions
diff --git a/source3/utils/regedit.c b/source3/utils/regedit.c index c0dbf9069e..8fca96bd18 100644 --- a/source3/utils/regedit.c +++ b/source3/utils/regedit.c @@ -86,53 +86,6 @@ static void print_path(struct regedit *regedit, struct tree_node *node) show_path(regedit); } -/* load all available hives */ -static struct tree_node *load_hives(struct regedit *regedit) -{ - const char *hives[] = { - "HKEY_CLASSES_ROOT", - "HKEY_CURRENT_USER", - "HKEY_LOCAL_MACHINE", - "HKEY_PERFORMANCE_DATA", - "HKEY_USERS", - "HKEY_CURRENT_CONFIG", - "HKEY_DYN_DATA", - "HKEY_PERFORMANCE_TEXT", - "HKEY_PERFORMANCE_NLSTEXT", - NULL - }; - struct tree_node *root, *prev, *node; - struct registry_key *key; - WERROR rv; - size_t i; - - root = NULL; - prev = NULL; - - for (i = 0; hives[i] != NULL; ++i) { - rv = reg_get_predefined_key_by_name(regedit->registry_context, - hives[i], &key); - if (!W_ERROR_IS_OK(rv)) { - continue; - } - - node = tree_node_new(regedit, NULL, hives[i], key); - if (node == NULL) { - return NULL; - } - - if (root == NULL) { - root = node; - } - if (prev) { - tree_node_append(prev, node); - } - prev = node; - } - - return root; -} - static void print_help(struct regedit *regedit) { const char *khelp = "[n] New Key [s] New Subkey [d] Del Key " @@ -196,7 +149,7 @@ static void add_reg_key(struct regedit *regedit, struct tree_node *node, const char *name; const char *msg; - if (!subkey && !node->parent) { + if (!subkey && tree_node_is_top_level(node)) { return; } @@ -387,7 +340,7 @@ static void handle_tree_input(struct regedit *regedit, int c) break; case KEY_LEFT: node = tree_view_get_current_node(regedit->keys); - if (node && node->parent) { + if (node && !tree_node_is_top_level(node)) { print_path(regedit, node->parent); node = node->parent; tree_view_update(regedit->keys, tree_node_first(node)); @@ -410,7 +363,7 @@ static void handle_tree_input(struct regedit *regedit, int c) int sel; node = tree_view_get_current_node(regedit->keys); - if (!node->parent) { + if (tree_node_is_top_level(node)) { break; } sel = dialog_notice(regedit, DIA_CONFIRM, @@ -537,8 +490,11 @@ static void handle_main_input(struct regedit *regedit, int c) node = tree_view_get_current_node(regedit->keys); path = tree_node_get_path(regedit, node); + SMB_ASSERT(path != NULL); + + root = tree_node_new_root(regedit, regedit->registry_context); + SMB_ASSERT(root != NULL); - root = load_hives(regedit); tree_view_set_root(regedit->keys, root); tree_view_set_path(regedit->keys, path); node = tree_view_get_current_node(regedit->keys); @@ -647,7 +603,7 @@ static void display_window(TALLOC_CTX *mem_ctx, struct registry_context *ctx) wprintw(regedit->path_label, "/"); show_path(regedit_main); - root = load_hives(regedit); + root = tree_node_new_root(regedit, ctx); SMB_ASSERT(root != NULL); regedit->keys = tree_view_new(regedit, root, KEY_HEIGHT, KEY_WIDTH, diff --git a/source3/utils/regedit_treeview.c b/source3/utils/regedit_treeview.c index 2f44613e8d..dd4b5cb08c 100644 --- a/source3/utils/regedit_treeview.c +++ b/source3/utils/regedit_treeview.c @@ -23,6 +23,12 @@ #define HEADING_X 3 +static int tree_node_free(struct tree_node *node) +{ + DEBUG(9, ("tree_node_free('%s', %p)\n", node->name, node)); + return 0; +} + struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, const char *name, struct registry_key *key) { @@ -32,6 +38,8 @@ struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, if (!node) { return NULL; } + talloc_set_destructor(node, tree_node_free); + DEBUG(9, ("tree_node_new('%s', %p)\n", name, node)); node->name = talloc_strdup(node, name); if (!node->name) { @@ -39,7 +47,9 @@ struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, return NULL; } - node->key = talloc_steal(node, key); + if (key) { + node->key = talloc_steal(node, key); + } if (parent) { /* Check if this node is the first descendant of parent. */ @@ -52,6 +62,52 @@ struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, return node; } +/* prepare a root node with all available hives as children */ +struct tree_node *tree_node_new_root(TALLOC_CTX *ctx, + struct registry_context *regctx) +{ + const char *hives[] = { + "HKEY_CLASSES_ROOT", + "HKEY_CURRENT_USER", + "HKEY_LOCAL_MACHINE", + "HKEY_PERFORMANCE_DATA", + "HKEY_USERS", + "HKEY_CURRENT_CONFIG", + "HKEY_DYN_DATA", + "HKEY_PERFORMANCE_TEXT", + "HKEY_PERFORMANCE_NLSTEXT", + NULL + }; + struct tree_node *root, *prev, *node; + struct registry_key *key; + WERROR rv; + size_t i; + + root = tree_node_new(ctx, NULL, "ROOT", NULL); + if (root == NULL) { + return NULL; + } + prev = NULL; + + for (i = 0; hives[i] != NULL; ++i) { + rv = reg_get_predefined_key_by_name(regctx, hives[i], &key); + if (!W_ERROR_IS_OK(rv)) { + continue; + } + + node = tree_node_new(root, root, hives[i], key); + if (node == NULL) { + return NULL; + } + if (prev) { + tree_node_append(prev, node); + } + prev = node; + } + + return root; +} + void tree_node_append(struct tree_node *left, struct tree_node *right) { if (left->next) { @@ -250,23 +306,6 @@ finish: return rv; } -void tree_node_free_recursive(struct tree_node *list) -{ - struct tree_node *node; - - if (list == NULL) { - return; - } - - while ((node = tree_node_pop(&list)) != NULL) { - if (node->child_head) { - tree_node_free_recursive(node->child_head); - } - node->child_head = NULL; - talloc_free(node); - } -} - void tree_view_clear(struct tree_view *view) { multilist_set_data(view->list, NULL); @@ -277,7 +316,7 @@ WERROR tree_view_set_root(struct tree_view *view, struct tree_node *root) multilist_set_data(view->list, NULL); talloc_free(view->root); view->root = root; - return tree_view_update(view, root); + return tree_view_update(view, root->child_head); } WERROR tree_view_set_path(struct tree_view *view, const char **path) @@ -285,7 +324,7 @@ WERROR tree_view_set_path(struct tree_view *view, const char **path) struct tree_node *top, *node; WERROR rv; - top = view->root; + top = view->root->child_head; while (*path) { for (node = top; node != NULL; node = node->next) { if (strcmp(*path, node->name) == 0) { @@ -377,7 +416,6 @@ static int tree_view_free(struct tree_view *view) if (view->window) { delwin(view->window); } - tree_node_free_recursive(view->root); return 0; } @@ -479,7 +517,7 @@ struct tree_view *tree_view_new(TALLOC_CTX *ctx, struct tree_node *root, if (view->list == NULL) { goto fail; } - tree_view_update(view, root); + tree_view_update(view, root->child_head); return view; @@ -520,7 +558,7 @@ const char **tree_node_get_path(TALLOC_CTX *ctx, struct tree_node *node) size_t nitems, index; struct tree_node *p; - for (nitems = 0, p = node; p != NULL; p = p->parent) { + for (nitems = 0, p = node; !tree_node_is_root(p); p = p->parent) { ++nitems; } @@ -529,7 +567,9 @@ const char **tree_node_get_path(TALLOC_CTX *ctx, struct tree_node *node) return NULL; } - for (index = nitems - 1, p = node; p != NULL; p = p->parent, --index) { + for (index = nitems - 1, p = node; + !tree_node_is_root(p); + p = p->parent, --index) { array[index] = talloc_strdup(array, p->name); if (array[index] == NULL) { talloc_free(discard_const(array)); @@ -553,7 +593,7 @@ size_t tree_node_print_path(WINDOW *label, struct tree_node *node) werase(label); wprintw(label, "/"); - if (node->parent == NULL) + if (tree_node_is_top_level(node)) return 0; frame = talloc_stackframe(); diff --git a/source3/utils/regedit_treeview.h b/source3/utils/regedit_treeview.h index 29c5fe2e65..4d1851ab1d 100644 --- a/source3/utils/regedit_treeview.h +++ b/source3/utils/regedit_treeview.h @@ -48,8 +48,14 @@ struct tree_view { struct multilist *list; }; +struct registry_context; + struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, const char *name, struct registry_key *key); +struct tree_node *tree_node_new_root(TALLOC_CTX *ctx, + struct registry_context *regctx); +#define tree_node_is_root(node) ((node)->key == NULL) +#define tree_node_is_top_level(node) tree_node_is_root((node)->parent) void tree_node_append(struct tree_node *left, struct tree_node *right); struct tree_node *tree_node_pop(struct tree_node **plist); struct tree_node *tree_node_first(struct tree_node *list); |