summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source3/utils/regedit.c8
-rw-r--r--source3/utils/regedit_treeview.c1
-rw-r--r--source3/utils/regedit_valuelist.c274
-rw-r--r--source3/utils/regedit_valuelist.h16
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