diff options
author | C. Davis <cd.rattan@gmail.com> | 2012-07-12 21:11:55 -0700 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2013-04-29 13:05:46 +0200 |
commit | d3633c08cd5e997d329ff42930d320a8eb4ac7f2 (patch) | |
tree | e268a51b4d3f8783727e97df2e684cf8cfdde00f | |
parent | c99675b813c9e7020f670542750320b9145b3096 (diff) | |
download | samba-d3633c08cd5e997d329ff42930d320a8eb4ac7f2.tar.gz samba-d3633c08cd5e997d329ff42930d320a8eb4ac7f2.tar.xz samba-d3633c08cd5e997d329ff42930d320a8eb4ac7f2.zip |
regedit: Setup a test tree view of HKLM.
Expand on the former test by allowing the user to walk HKLM
with the tree view. Subkeys are loaded dynamically in memory
as the user walks the hierarchy with tree_node_load_children().
One issue with this at the moment is detecting if the
in-memory copy of the hierarchy is out of date.
TODO: figure out when to reload out of date portions of the
hierarchy (probably by checking last_modified_time).
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
-rw-r--r-- | source3/utils/regedit.c | 90 | ||||
-rw-r--r-- | source3/utils/regedit_treeview.c | 79 | ||||
-rw-r--r-- | source3/utils/regedit_treeview.h | 7 |
3 files changed, 147 insertions, 29 deletions
diff --git a/source3/utils/regedit.c b/source3/utils/regedit.c index 5ae21201fb4..79b05a0c1e4 100644 --- a/source3/utils/regedit.c +++ b/source3/utils/regedit.c @@ -22,9 +22,70 @@ #include "lib/util/data_blob.h" #include "lib/registry/registry.h" #include "regedit.h" +#include "regedit_treeview.h" #include <ncurses.h> #include <menu.h> +/* test navigating HKLM hierarchy */ +static void display_test_window(TALLOC_CTX *mem_ctx, struct registry_context *ctx) +{ + WINDOW *tree_window; + struct tree_view *view; + struct tree_node *root, *node; + struct registry_key *key; + int c; + WERROR rv; + + initscr(); + start_color(); + cbreak(); + noecho(); + keypad(stdscr, TRUE); + + tree_window = newwin(25, 80, 0, 0); + + keypad(tree_window, TRUE); + + rv = reg_get_predefined_key_by_name(ctx, "HKEY_LOCAL_MACHINE", &key); + SMB_ASSERT(W_ERROR_IS_OK(rv)); + + root = tree_node_new(mem_ctx, NULL, "HKEY_LOCAL_MACHINE", key); + SMB_ASSERT(root != NULL); + + view = tree_view_new(mem_ctx, root, tree_window, 15, 40, 3, 0); + SMB_ASSERT(root != NULL); + refresh(); + tree_view_show(view); + + while ((c = wgetch(tree_window)) != 'q') { + switch (c) { + case KEY_DOWN: + menu_driver(view->menu, REQ_DOWN_ITEM); + break; + case KEY_UP: + menu_driver(view->menu, REQ_UP_ITEM); + break; + case KEY_RIGHT: + node = item_userptr(current_item(view->menu)); + if (node && tree_node_has_children(node)) { + tree_node_load_children(node); + tree_view_update(view, node->child_head); + } + break; + case KEY_LEFT: + node = item_userptr(current_item(view->menu)); + if (node && node->parent) { + tree_view_update(view, + tree_node_first(node->parent)); + } + break; + } + tree_view_show(view); + } + + endwin(); +} + int main(int argc, char **argv) { struct poptOption long_options[] = { @@ -40,13 +101,9 @@ int main(int argc, char **argv) struct user_auth_info *auth_info; TALLOC_CTX *frame; struct registry_context *ctx; - struct registry_key *hklm; - struct registry_key *smbconf; - uint32_t n; WERROR rv; - initscr(); - endwin(); + talloc_enable_leak_report_full(); frame = talloc_stackframe(); @@ -71,28 +128,9 @@ int main(int argc, char **argv) rv = reg_open_samba3(frame, &ctx); SMB_ASSERT(W_ERROR_IS_OK(rv)); - rv = reg_get_predefined_key_by_name(ctx, "HKEY_LOCAL_MACHINE", &hklm); - SMB_ASSERT(W_ERROR_IS_OK(rv)); - - printf("contents of hklm/SOFTWARE/Samba/smbconf...\n"); + display_test_window(frame, ctx); - rv = reg_open_key(ctx, hklm, "SOFTWARE\\Samba\\smbconf", &smbconf); - SMB_ASSERT(W_ERROR_IS_OK(rv)); - - printf("subkeys...\n"); - - for (n = 0; ;++n) { - const char *name, *klass; - NTTIME modified; - - rv = reg_key_get_subkey_by_index(ctx, smbconf, n, &name, - &klass, &modified); - if (!W_ERROR_IS_OK(rv)) { - break; - } - - printf("%u: %s\n", (unsigned)n, name); - } + //talloc_report_full(frame, stdout); TALLOC_FREE(frame); diff --git a/source3/utils/regedit_treeview.c b/source3/utils/regedit_treeview.c index f902f606781..ad6d45c7eca 100644 --- a/source3/utils/regedit_treeview.c +++ b/source3/utils/regedit_treeview.c @@ -18,8 +18,10 @@ */ #include "regedit_treeview.h" +#include "lib/registry/registry.h" -struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, const char *name) +struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, + const char *name, struct registry_key *key) { struct tree_node *node; @@ -34,6 +36,8 @@ struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, const return NULL; } + node->key = talloc_steal(node, key); + if (parent) { /* Check if this node is the first descendant of parent. */ if (!parent->child_head) { @@ -95,6 +99,77 @@ struct tree_node *tree_node_first(struct tree_node *list) return list; } +bool tree_node_has_children(struct tree_node *node) +{ + const char *classname; + uint32_t num_subkeys; + uint32_t num_values; + NTTIME last_change_time; + uint32_t max_subkeynamelen; + uint32_t max_valnamelen; + uint32_t max_valbufsize; + WERROR rv; + + if (node->child_head) { + return true; + } + + rv = reg_key_get_info(node, node->key, &classname, &num_subkeys, + &num_values, &last_change_time, + &max_subkeynamelen, &max_valnamelen, + &max_valbufsize); + + if (W_ERROR_IS_OK(rv)) { + return num_subkeys != 0; + } + + return false; +} + +WERROR tree_node_load_children(struct tree_node *node) +{ + struct registry_key *key; + const char *key_name, *klass; + NTTIME modified; + uint32_t i; + WERROR rv; + struct tree_node *new_node, *prev; + + /* does this node already have it's children loaded? */ + if (node->child_head) + return WERR_OK; + + for (prev = NULL, i = 0; ; ++i) { + rv = reg_key_get_subkey_by_index(node, node->key, i, + &key_name, &klass, + &modified); + if (!W_ERROR_IS_OK(rv)) { + if (W_ERROR_EQUAL(rv, WERR_NO_MORE_ITEMS)) { + break; + } + + return rv; + } + + rv = reg_open_key(node, node->key, key_name, &key); + if (!W_ERROR_IS_OK(rv)) { + return rv; + } + + new_node = tree_node_new(node, node, key_name, key); + if (new_node == NULL) { + return WERR_NOMEM; + } + + if (prev) { + tree_node_append(prev, new_node); + } + prev = new_node; + } + + return WERR_OK; +} + void tree_node_free_recursive(struct tree_node *list) { struct tree_node *node; @@ -158,7 +233,7 @@ WERROR tree_view_update(struct tree_view *view, struct tree_node *list) /* Add a '+' marker to indicate that the item has descendants. */ - if (node->child_head) { + if (tree_node_has_children(node)) { SMB_ASSERT(node->label == NULL); node->label = talloc_asprintf(node, "+%s", node->name); if (node->label == NULL) { diff --git a/source3/utils/regedit_treeview.h b/source3/utils/regedit_treeview.h index 1af6ad34589..5be542514a1 100644 --- a/source3/utils/regedit_treeview.h +++ b/source3/utils/regedit_treeview.h @@ -24,10 +24,13 @@ #include <ncurses.h> #include <menu.h> +struct registry_key; + struct tree_node { char *name; char *label; + struct registry_key *key; struct tree_node *parent; struct tree_node *child_head; @@ -45,7 +48,7 @@ struct tree_view { }; struct tree_node *tree_node_new(TALLOC_CTX *ctx, struct tree_node *parent, - const char *name); + const char *name, struct registry_key *key); 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); @@ -56,5 +59,7 @@ struct tree_view *tree_view_new(TALLOC_CTX *ctx, struct tree_node *root, int begin_y, int begin_x); void tree_view_show(struct tree_view *view); WERROR tree_view_update(struct tree_view *view, struct tree_node *list); +bool tree_node_has_children(struct tree_node *node); +WERROR tree_node_load_children(struct tree_node *node); #endif |