diff options
Diffstat (limited to 'source3/utils')
-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 5ae21201fb..79b05a0c1e 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 f902f60678..ad6d45c7ec 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 1af6ad3458..5be542514a 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 |