#define PATH_WIDTH_MAX 1024
struct regedit {
+ struct registry_context *registry_context;
WINDOW *main_window;
WINDOW *path_label;
size_t path_len;
}
/* load all available hives */
-static struct tree_node *load_hives(TALLOC_CTX *mem_ctx,
- struct registry_context *ctx)
+static struct tree_node *load_hives(struct regedit *regedit)
{
const char *hives[] = {
"HKEY_CLASSES_ROOT",
prev = NULL;
for (i = 0; hives[i] != NULL; ++i) {
- rv = reg_get_predefined_key_by_name(ctx, hives[i], &key);
+ rv = reg_get_predefined_key_by_name(regedit->registry_context,
+ hives[i], &key);
if (!W_ERROR_IS_OK(rv)) {
continue;
}
- node = tree_node_new(mem_ctx, NULL, hives[i], key);
+ node = tree_node_new(regedit, NULL, hives[i], key);
if (node == NULL) {
return NULL;
}
tree_node_reopen_key(parent);
tree_view_clear(regedit->keys);
pop = tree_node_pop(&node);
- tree_node_free_recursive(pop);
+ talloc_free(pop);
node = parent->child_head;
if (node == NULL) {
node = tree_node_first(parent);
static void handle_main_input(struct regedit *regedit, int c)
{
switch (c) {
+ case 18: { /* CTRL-R */
+ struct tree_node *root, *node;
+ const char **path;
+
+ node = tree_view_get_current_node(regedit->keys);
+ path = tree_node_get_path(regedit, node);
+
+ 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);
+ value_list_load(regedit->vl, node->key);
+ tree_view_show(regedit->keys);
+ value_list_show(regedit->vl);
+ print_path(regedit, node);
+ talloc_free(discard_const(path));
+ break;
+ }
case 'f':
case 'F':
case '/': {
SMB_ASSERT(regedit != NULL);
regedit_main = regedit;
+ regedit->registry_context = ctx;
regedit->main_window = stdscr;
keypad(regedit->main_window, TRUE);
wprintw(regedit->path_label, "/");
show_path(regedit_main);
- root = load_hives(regedit, ctx);
+ root = load_hives(regedit);
SMB_ASSERT(root != NULL);
regedit->keys = tree_view_new(regedit, root, KEY_HEIGHT, KEY_WIDTH,
multilist_set_data(view->list, NULL);
}
+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);
+}
+
+WERROR tree_view_set_path(struct tree_view *view, const char **path)
+{
+ struct tree_node *top, *node;
+ WERROR rv;
+
+ top = view->root;
+ while (*path) {
+ for (node = top; node != NULL; node = node->next) {
+ if (strcmp(*path, node->name) == 0) {
+ if (path[1] && tree_node_has_children(node)) {
+ rv = tree_node_load_children(node);
+ if (!W_ERROR_IS_OK(rv)) {
+ return rv;
+ }
+ SMB_ASSERT(node->child_head);
+ top = node->child_head;
+ break;
+ } else {
+ tree_view_update(view, top);
+ tree_view_set_current_node(view, node);
+ return WERR_OK;
+ }
+ }
+ }
+ ++path;
+ }
+
+ return WERR_OK;
+}
+
WERROR tree_view_update(struct tree_view *view, struct tree_node *list)
{
WERROR rv;
tree_view_show(view);
}
-static void print_path_recursive(WINDOW *label, struct tree_node *node,
- size_t *len)
+const char **tree_node_get_path(TALLOC_CTX *ctx, struct tree_node *node)
{
- if (node->parent)
- print_path_recursive(label, node->parent, len);
+ const char **array;
+ size_t nitems, index;
+ struct tree_node *p;
- wprintw(label, "%s/", node->name);
- *len += 1 + strlen(node->name);
+ for (nitems = 0, p = node; p != NULL; p = p->parent) {
+ ++nitems;
+ }
+
+ array = talloc_zero_array(ctx, const char *, nitems + 1);
+ if (array == NULL) {
+ return NULL;
+ }
+
+ for (index = nitems - 1, p = node; p != NULL; p = p->parent, --index) {
+ array[index] = talloc_strdup(array, p->name);
+ if (array[index] == NULL) {
+ talloc_free(discard_const(array));
+ return NULL;
+ }
+ }
+
+ return array;
}
/* print the path of node to label */
size_t tree_node_print_path(WINDOW *label, struct tree_node *node)
{
size_t len = 1;
+ const char **path;
+ TALLOC_CTX *frame;
if (node == NULL)
return 0;
werase(label);
wprintw(label, "/");
- if (node->parent)
- print_path_recursive(label, node->parent, &len);
+ if (node->parent == NULL)
+ return 0;
+
+ frame = talloc_stackframe();
+ path = tree_node_get_path(frame, node->parent);
+
+ while (*path) {
+ len += strlen(*path) + 1;
+ wprintw(label, "%s/", *path);
+ ++path;
+ }
+
+ talloc_free(frame);
return len;
}
struct tree_node *tree_node_first(struct tree_node *list);
struct tree_node *tree_node_last(struct tree_node *list);
void tree_node_append_last(struct tree_node *list, struct tree_node *node);
-void tree_node_free_recursive(struct tree_node *list);
size_t tree_node_print_path(WINDOW *label, struct tree_node *node);
+const char **tree_node_get_path(TALLOC_CTX *ctx, struct tree_node *node);
struct tree_view *tree_view_new(TALLOC_CTX *ctx, struct tree_node *root,
int nlines, int ncols,
int begin_y, int begin_x);
int begin_y, int begin_x);
void tree_view_show(struct tree_view *view);
void tree_view_clear(struct tree_view *view);
+WERROR tree_view_set_root(struct tree_view *view, struct tree_node *root);
+WERROR tree_view_set_path(struct tree_view *view, const char **path);
WERROR tree_view_update(struct tree_view *view, struct tree_node *list);
WERROR tree_node_reopen_key(struct tree_node *node);
bool tree_node_has_children(struct tree_node *node);