summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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