summaryrefslogtreecommitdiff
path: root/source3/utils
diff options
context:
space:
mode:
authorC. Davis <cd.rattan@gmail.com>2012-07-12 21:11:55 -0700
committerMichael Adam <obnox@samba.org>2013-04-29 13:05:46 +0200
commitd3633c08cd5e997d329ff42930d320a8eb4ac7f2 (patch)
treee268a51b4d3f8783727e97df2e684cf8cfdde00f /source3/utils
parentc99675b813c9e7020f670542750320b9145b3096 (diff)
downloadsamba-d3633c08cd5e997d329ff42930d320a8eb4ac7f2.tar.gz
samba-d3633c08cd5e997d329ff42930d320a8eb4ac7f2.tar.bz2
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>
Diffstat (limited to 'source3/utils')
-rw-r--r--source3/utils/regedit.c90
-rw-r--r--source3/utils/regedit_treeview.c79
-rw-r--r--source3/utils/regedit_treeview.h7
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