2 * Samba Unix/Linux SMB client library
4 * Copyright (C) Christopher Davis 2012
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "regedit_valuelist.h"
21 #include "lib/registry/registry.h"
25 static void value_list_free_items(ITEM **items)
29 struct value_item *vitem;
35 for (i = 0; items[i] != NULL; ++i) {
37 vitem = item_userptr(item);
38 SMB_ASSERT(vitem != NULL);
45 static int value_list_free(struct value_list *vl)
48 unpost_menu(vl->menu);
51 if (vl->empty && vl->empty[0]) {
52 free_item(vl->empty[0]);
63 value_list_free_items(vl->items);
68 struct value_list *value_list_new(TALLOC_CTX *ctx, int nlines, int ncols,
69 int begin_y, int begin_x)
71 static const char *empty = "(no values)";
72 static const char *empty_desc = "";
73 struct value_list *vl;
75 vl = talloc_zero(ctx, struct value_list);
80 talloc_set_destructor(vl, value_list_free);
82 vl->empty = talloc_zero_array(vl, ITEM *, 2);
83 if (vl->empty == NULL) {
86 vl->empty[0] = new_item(empty, empty_desc);
87 if (vl->empty[0] == NULL) {
91 vl->window = newwin(nlines, ncols, begin_y, begin_x);
92 if (vl->window == NULL) {
95 vl->sub = subwin(vl->window, nlines - 2, ncols - 2,
96 begin_y + 1, begin_x + 1);
97 if (vl->sub == NULL) {
100 box(vl->window, 0, 0);
101 mvwprintw(vl->window, 0, HEADING_X, "Value");
103 vl->panel = new_panel(vl->window);
104 if (vl->panel == NULL) {
108 vl->menu = new_menu(vl->empty);
109 if (vl->menu == NULL) {
113 set_menu_format(vl->menu, nlines, 1);
114 set_menu_win(vl->menu, vl->window);
115 set_menu_sub(vl->menu, vl->sub);
117 menu_opts_on(vl->menu, O_SHOWDESC);
118 set_menu_mark(vl->menu, "* ");
128 void value_list_set_selected(struct value_list *vl, bool select)
130 attr_t attr = A_NORMAL;
135 mvwchgat(vl->window, 0, HEADING_X, 5, attr, 0, NULL);
138 void value_list_resize(struct value_list *vl, int nlines, int ncols,
139 int begin_y, int begin_x)
143 unpost_menu(vl->menu);
144 nwin = newwin(nlines, ncols, begin_y, begin_x);
145 nsub = subwin(nwin, nlines - 2, ncols - 2, begin_y + 1, begin_x + 1);
146 replace_panel(vl->panel, nwin);
151 box(vl->window, 0, 0);
152 mvwprintw(vl->window, 0, HEADING_X, "Value");
153 set_menu_format(vl->menu, nlines, 1);
154 set_menu_win(vl->menu, vl->window);
155 set_menu_sub(vl->menu, vl->sub);
159 static uint32_t get_num_values(TALLOC_CTX *ctx, const struct registry_key *key)
161 const char *classname;
162 uint32_t num_subkeys;
164 NTTIME last_change_time;
165 uint32_t max_subkeynamelen;
166 uint32_t max_valnamelen;
167 uint32_t max_valbufsize;
170 rv = reg_key_get_info(ctx, key, &classname, &num_subkeys,
171 &num_values, &last_change_time,
172 &max_subkeynamelen, &max_valnamelen,
175 if (W_ERROR_IS_OK(rv)) {
182 void value_list_show(struct value_list *vl)
187 static bool string_is_printable(const char *s)
191 for (p = s; *p; ++p) {
200 static WERROR append_data_summary(struct value_item *vitem)
204 /* This is adapted from print_registry_value() in net_registry_util.c */
206 switch(vitem->type) {
209 if (vitem->data.length >= 4) {
210 v = IVAL(vitem->data.data, 0);
212 tmp = talloc_asprintf_append(vitem->value_desc, "(0x%x)", v);
216 case REG_EXPAND_SZ: {
219 if (!pull_reg_sz(vitem, &vitem->data, &s)) {
222 vitem->unprintable = !string_is_printable(s);
223 if (vitem->unprintable) {
224 tmp = talloc_asprintf_append(vitem->value_desc,
227 tmp = talloc_asprintf_append(vitem->value_desc,
236 if (!pull_reg_multi_sz(vitem, &vitem->data, &a)) {
239 tmp = vitem->value_desc;
240 for (i = 0; a[i] != NULL; ++i) {
241 if (!string_is_printable(a[i])) {
242 tmp = talloc_asprintf_append(tmp,
244 vitem->unprintable = true;
246 tmp = talloc_asprintf_append(tmp, "\"%s\" ",
256 tmp = talloc_asprintf_append(vitem->value_desc, "(%d bytes)",
257 (int)vitem->data.length);
260 tmp = talloc_asprintf_append(vitem->value_desc,
269 vitem->value_desc = tmp;
274 WERROR value_list_load(struct value_list *vl, struct registry_key *key)
278 struct value_item *vitem;
281 static const char *empty_name = "(empty)";
284 unpost_menu(vl->menu);
286 n_values = get_num_values(vl, key);
288 set_menu_items(vl->menu, vl->empty);
292 new_items = talloc_zero_array(vl, ITEM *, n_values + 1);
293 if (new_items == NULL) {
297 for (idx = 0; idx < n_values; ++idx) {
298 vitem = talloc_zero(new_items, struct value_item);
303 rv = reg_key_get_value_by_index(vitem, key, idx,
308 if (!W_ERROR_IS_OK(rv)) {
313 vitem->value_desc = talloc_asprintf(vitem, "%-14s",
314 str_regtype(vitem->type));
315 if (vitem->value_desc == NULL) {
320 rv = append_data_summary(vitem);
321 if (!W_ERROR_IS_OK(rv)) {
326 /* ncurses won't accept empty strings in menu items */
327 name = vitem->value_name;
328 if (name[0] == '\0') {
331 new_items[idx] = new_item(name, vitem->value_desc);
332 if (new_items[idx] == NULL) {
337 set_item_userptr(new_items[idx], vitem);
340 set_menu_items(vl->menu, new_items);
341 value_list_free_items(vl->items);
342 vl->items = new_items;