diff options
-rw-r--r-- | source3/utils/regedit.c | 8 | ||||
-rw-r--r-- | source3/utils/regedit_treeview.c | 1 | ||||
-rw-r--r-- | source3/utils/regedit_valuelist.c | 274 | ||||
-rw-r--r-- | source3/utils/regedit_valuelist.h | 16 |
4 files changed, 171 insertions, 128 deletions
diff --git a/source3/utils/regedit.c b/source3/utils/regedit.c index ea9aec8976..b8f442c346 100644 --- a/source3/utils/regedit.c +++ b/source3/utils/regedit.c @@ -435,10 +435,10 @@ static void handle_value_input(struct regedit *regedit, int c) switch (c) { case KEY_DOWN: - menu_driver(regedit->vl->menu, REQ_DOWN_ITEM); + value_list_driver(regedit->vl, ML_CURSOR_DOWN); break; case KEY_UP: - menu_driver(regedit->vl->menu, REQ_UP_ITEM); + value_list_driver(regedit->vl, ML_CURSOR_UP); break; case 'b': case 'B': @@ -446,7 +446,7 @@ static void handle_value_input(struct regedit *regedit, int c) /* Falthrough... */ case '\n': case KEY_ENTER: - vitem = item_userptr(current_item(regedit->vl->menu)); + vitem = value_list_get_current_item(regedit->vl); if (vitem) { struct tree_node *node; node = tree_view_get_current_node(regedit->keys); @@ -472,7 +472,7 @@ static void handle_value_input(struct regedit *regedit, int c) } case 'd': case 'D': - vitem = item_userptr(current_item(regedit->vl->menu)); + vitem = value_list_get_current_item(regedit->vl); if (vitem) { int sel; diff --git a/source3/utils/regedit_treeview.c b/source3/utils/regedit_treeview.c index 7e65c39937..ee6b631521 100644 --- a/source3/utils/regedit_treeview.c +++ b/source3/utils/regedit_treeview.c @@ -445,6 +445,7 @@ void tree_view_resize(struct tree_view *view, int nlines, int ncols, box(view->window, 0, 0); mvwprintw(view->window, 0, HEADING_X, "Key"); multilist_set_window(view->list, view->sub); + tree_view_show(view); } static void print_path_recursive(WINDOW *label, struct tree_node *node, diff --git a/source3/utils/regedit_valuelist.c b/source3/utils/regedit_valuelist.c index 791a8caeda..4922cdb388 100644 --- a/source3/utils/regedit_valuelist.c +++ b/source3/utils/regedit_valuelist.c @@ -18,39 +18,13 @@ */ #include "regedit_valuelist.h" +#include "regedit_list.h" #include "lib/registry/registry.h" #define HEADING_X 3 -static void value_list_free_items(ITEM **items) -{ - size_t i; - ITEM *item; - struct value_item *vitem; - - if (items == NULL) { - return; - } - - for (i = 0; items[i] != NULL; ++i) { - item = items[i]; - vitem = item_userptr(item); - SMB_ASSERT(vitem != NULL); - free_item(item); - } - - talloc_free(items); -} - static int value_list_free(struct value_list *vl) { - if (vl->menu) { - unpost_menu(vl->menu); - free_menu(vl->menu); - } - if (vl->empty && vl->empty[0]) { - free_item(vl->empty[0]); - } if (vl->panel) { del_panel(vl->panel); } @@ -60,16 +34,94 @@ static int value_list_free(struct value_list *vl) if (vl->window) { delwin(vl->window); } - value_list_free_items(vl->items); return 0; } +static const char *vl_get_column_header(const void *data, unsigned col) +{ + switch (col) { + case 0: + return "Name"; + case 1: + return "Type"; + case 2: + return "Data"; + } + + return "???"; +} + +static const void *vl_get_first_row(const void *data) +{ + const struct value_list *vl = data; + + if (vl && vl->nvalues) { + return &vl->values[0]; + } + return NULL; +} + +static const void *vl_get_next_row(const void *data, const void *row) +{ + const struct value_list *vl = data; + const struct value_item *value = row; + + SMB_ASSERT(vl != NULL); + SMB_ASSERT(value != NULL); + if (value == &vl->values[vl->nvalues - 1]) { + return NULL; + } + + return value + 1; +} + +static const void *vl_get_prev_row(const void *data, const void *row) +{ + const struct value_list *vl = data; + const struct value_item *value = row; + + SMB_ASSERT(vl != NULL); + SMB_ASSERT(value != NULL); + if (value == &vl->values[0]) { + return NULL; + } + + return value - 1; +} + +static const char *vl_get_item_label(const void *row, unsigned col) +{ + const struct value_item *value = row; + + SMB_ASSERT(value != NULL); + SMB_ASSERT(value->value_name != NULL); + switch (col) { + case 0: + return value->value_name; + case 1: + return str_regtype(value->type); + case 2: + if (value->value) { + return value->value; + } + return ""; + } + + return "???"; +} + +static struct multilist_accessors vl_accessors = { + .get_column_header = vl_get_column_header, + .get_first_row = vl_get_first_row, + .get_next_row = vl_get_next_row, + .get_prev_row = vl_get_prev_row, + .get_item_label = vl_get_item_label +}; + struct value_list *value_list_new(TALLOC_CTX *ctx, int nlines, int ncols, int begin_y, int begin_x) { - static const char *empty = "(no values)"; - static const char *empty_desc = ""; struct value_list *vl; vl = talloc_zero(ctx, struct value_list); @@ -79,15 +131,6 @@ struct value_list *value_list_new(TALLOC_CTX *ctx, int nlines, int ncols, talloc_set_destructor(vl, value_list_free); - vl->empty = talloc_zero_array(vl, ITEM *, 2); - if (vl->empty == NULL) { - goto fail; - } - vl->empty[0] = new_item(empty, empty_desc); - if (vl->empty[0] == NULL) { - goto fail; - } - vl->window = newwin(nlines, ncols, begin_y, begin_x); if (vl->window == NULL) { goto fail; @@ -105,18 +148,11 @@ struct value_list *value_list_new(TALLOC_CTX *ctx, int nlines, int ncols, goto fail; } - vl->menu = new_menu(vl->empty); - if (vl->menu == NULL) { + vl->list = multilist_new(vl, vl->sub, &vl_accessors, 3); + if (vl->list == NULL) { goto fail; } - set_menu_format(vl->menu, nlines, 1); - set_menu_win(vl->menu, vl->window); - set_menu_sub(vl->menu, vl->sub); - - menu_opts_on(vl->menu, O_SHOWDESC); - set_menu_mark(vl->menu, "* "); - return vl; fail: @@ -140,7 +176,6 @@ void value_list_resize(struct value_list *vl, int nlines, int ncols, { WINDOW *nwin, *nsub; - unpost_menu(vl->menu); nwin = newwin(nlines, ncols, begin_y, begin_x); nsub = subwin(nwin, nlines - 2, ncols - 2, begin_y + 1, begin_x + 1); replace_panel(vl->panel, nwin); @@ -150,10 +185,8 @@ void value_list_resize(struct value_list *vl, int nlines, int ncols, vl->sub = nsub; box(vl->window, 0, 0); mvwprintw(vl->window, 0, HEADING_X, "Value"); - set_menu_format(vl->menu, nlines, 1); - set_menu_win(vl->menu, vl->window); - set_menu_sub(vl->menu, vl->sub); - post_menu(vl->menu); + multilist_set_window(vl->list, vl->sub); + value_list_show(vl); } static uint32_t get_num_values(TALLOC_CTX *ctx, const struct registry_key *key) @@ -181,7 +214,10 @@ static uint32_t get_num_values(TALLOC_CTX *ctx, const struct registry_key *key) void value_list_show(struct value_list *vl) { - post_menu(vl->menu); + multilist_refresh(vl->list); + touchwin(vl->window); + wnoutrefresh(vl->window); + wnoutrefresh(vl->sub); } static bool string_is_printable(const char *s) @@ -197,7 +233,7 @@ static bool string_is_printable(const char *s) return true; } -static WERROR append_data_summary(struct value_item *vitem) +static WERROR append_data_summary(TALLOC_CTX *ctx, struct value_item *vitem) { char *tmp = NULL; @@ -209,42 +245,53 @@ static WERROR append_data_summary(struct value_item *vitem) if (vitem->data.length >= 4) { v = IVAL(vitem->data.data, 0); } - tmp = talloc_asprintf_append(vitem->value_desc, "(0x%x)", v); + tmp = talloc_asprintf(ctx, "0x%08x (%u)", v, v); break; } case REG_SZ: case REG_EXPAND_SZ: { const char *s; - if (!pull_reg_sz(vitem, &vitem->data, &s)) { + if (!pull_reg_sz(ctx, &vitem->data, &s)) { break; } vitem->unprintable = !string_is_printable(s); if (vitem->unprintable) { - tmp = talloc_asprintf_append(vitem->value_desc, - "(unprintable)"); + tmp = talloc_asprintf(ctx, "(unprintable)"); } else { - tmp = talloc_asprintf_append(vitem->value_desc, - "(\"%s\")", s); + tmp = talloc_asprintf(ctx, "%s", s); } break; } case REG_MULTI_SZ: { - size_t i; + size_t i, len; const char **a; + const char *val; - if (!pull_reg_multi_sz(vitem, &vitem->data, &a)) { + if (!pull_reg_multi_sz(ctx, &vitem->data, &a)) { break; } - tmp = vitem->value_desc; - for (i = 0; a[i] != NULL; ++i) { + for (len = 0; a[len] != NULL; ++len) { + } + tmp = talloc_asprintf(ctx, "(%u) ", (unsigned)len); + if (tmp == NULL) { + return WERR_NOMEM; + } + for (i = 0; i < len; ++i) { if (!string_is_printable(a[i])) { - tmp = talloc_asprintf_append(tmp, - "(unprintable)"); + val = "(unprintable)"; vitem->unprintable = true; } else { - tmp = talloc_asprintf_append(tmp, "\"%s\" ", - a[i]); + val = a[i]; + } + if (i == len - 1) { + tmp = talloc_asprintf_append(tmp, + "[%u]=\"%s\"", + (unsigned)i, val); + } else { + tmp = talloc_asprintf_append(tmp, + "[%u]=\"%s\", ", + (unsigned)i, val); } if (tmp == NULL) { return WERR_NOMEM; @@ -253,12 +300,11 @@ static WERROR append_data_summary(struct value_item *vitem) break; } case REG_BINARY: - tmp = talloc_asprintf_append(vitem->value_desc, "(%d bytes)", - (int)vitem->data.length); + tmp = talloc_asprintf(ctx, "(%d bytes)", + (int)vitem->data.length); break; default: - tmp = talloc_asprintf_append(vitem->value_desc, - "(<unprintable>)"); + tmp = talloc_asprintf(ctx, "(unknown)"); break; } @@ -266,80 +312,74 @@ static WERROR append_data_summary(struct value_item *vitem) return WERR_NOMEM; } - vitem->value_desc = tmp; + vitem->value = tmp; return WERR_OK; } +static int vitem_cmp(struct value_item *a, struct value_item *b) +{ + return strcmp(a->value_name, b->value_name); +} + WERROR value_list_load(struct value_list *vl, struct registry_key *key) { - uint32_t n_values; + uint32_t nvalues; uint32_t idx; - struct value_item *vitem; - ITEM **new_items; + struct value_item *vitem, *new_items; WERROR rv; - static const char *empty_name = "(empty)"; - const char *name; - unpost_menu(vl->menu); + multilist_set_data(vl->list, NULL); + vl->nvalues = 0; + TALLOC_FREE(vl->values); - n_values = get_num_values(vl, key); - if (n_values == 0) { - set_menu_items(vl->menu, vl->empty); + nvalues = get_num_values(vl, key); + if (nvalues == 0) { return WERR_OK; } - new_items = talloc_zero_array(vl, ITEM *, n_values + 1); + new_items = talloc_zero_array(vl, struct value_item, nvalues); if (new_items == NULL) { return WERR_NOMEM; } - for (idx = 0; idx < n_values; ++idx) { - vitem = talloc_zero(new_items, struct value_item); - if (vitem == NULL) { - return WERR_NOMEM; - } - - rv = reg_key_get_value_by_index(vitem, key, idx, + for (idx = 0; idx < nvalues; ++idx) { + vitem = &new_items[idx]; + rv = reg_key_get_value_by_index(new_items, key, idx, &vitem->value_name, &vitem->type, &vitem->data); - if (!W_ERROR_IS_OK(rv)) { - talloc_free(vitem); + talloc_free(new_items); return rv; } - vitem->value_desc = talloc_asprintf(vitem, "%-14s", - str_regtype(vitem->type)); - if (vitem->value_desc == NULL) { - talloc_free(vitem); - return rv; - } - - rv = append_data_summary(vitem); + rv = append_data_summary(new_items, vitem); if (!W_ERROR_IS_OK(rv)) { - talloc_free(vitem); + talloc_free(new_items); return rv; } + } - /* ncurses won't accept empty strings in menu items */ - name = vitem->value_name; - if (name[0] == '\0') { - name = empty_name; - } - new_items[idx] = new_item(name, vitem->value_desc); - if (new_items[idx] == NULL) { - talloc_free(vitem); - return WERR_NOMEM; - } + TYPESAFE_QSORT(new_items, nvalues, vitem_cmp); - set_item_userptr(new_items[idx], vitem); + vl->nvalues = nvalues; + vl->values = new_items; + rv = multilist_set_data(vl->list, vl); + if (W_ERROR_IS_OK(rv)) { + multilist_refresh(vl->list); } - set_menu_items(vl->menu, new_items); - value_list_free_items(vl->items); - vl->items = new_items; + return rv; +} - return WERR_OK; +struct value_item *value_list_get_current_item(struct value_list *vl) +{ + return discard_const_p(struct value_item, + multilist_get_current_row(vl->list)); +} + +void value_list_driver(struct value_list *vl, int c) +{ + multilist_driver(vl->list, c); } diff --git a/source3/utils/regedit_valuelist.h b/source3/utils/regedit_valuelist.h index 16b0d502b7..ea67075d14 100644 --- a/source3/utils/regedit_valuelist.h +++ b/source3/utils/regedit_valuelist.h @@ -22,7 +22,6 @@ #include "includes.h" #include <ncurses.h> -#include <menu.h> #include <panel.h> struct registry_key; @@ -31,19 +30,20 @@ struct value_item { uint32_t type; DATA_BLOB data; const char *value_name; - char *value_desc; + char *value; bool unprintable; }; +struct multilist; + struct value_list { WINDOW *window; WINDOW *sub; PANEL *panel; - MENU *menu; - ITEM **items; - ITEM **empty; -} -; + size_t nvalues; + struct value_item *values; + struct multilist *list; +}; struct value_list *value_list_new(TALLOC_CTX *ctx, int nlines, int ncols, int begin_y, int begin_x); void value_list_show(struct value_list *vl); @@ -51,5 +51,7 @@ void value_list_set_selected(struct value_list *vl, bool select); WERROR value_list_load(struct value_list *vl, struct registry_key *key); void value_list_resize(struct value_list *vl, int nlines, int ncols, int begin_y, int begin_x); +struct value_item *value_list_get_current_item(struct value_list *vl); +void value_list_driver(struct value_list *vl, int c); #endif |