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"
23 static void value_list_free_items(ITEM
**items
)
27 struct value_item
*vitem
;
33 for (i
= 0; items
[i
] != NULL
; ++i
) {
35 vitem
= item_userptr(item
);
36 SMB_ASSERT(vitem
!= NULL
);
43 static int value_list_free(struct value_list
*vl
)
46 unpost_menu(vl
->menu
);
49 if (vl
->empty
&& vl
->empty
[0]) {
50 free_item(vl
->empty
[0]);
58 value_list_free_items(vl
->items
);
63 struct value_list
*value_list_new(TALLOC_CTX
*ctx
, int nlines
, int ncols
,
64 int begin_y
, int begin_x
)
66 static const char *empty
= "(no values)";
67 static const char *empty_desc
= "";
68 struct value_list
*vl
;
70 vl
= talloc_zero(ctx
, struct value_list
);
75 talloc_set_destructor(vl
, value_list_free
);
77 vl
->empty
= talloc_zero_array(vl
, ITEM
*, 2);
78 if (vl
->empty
== NULL
) {
81 vl
->empty
[0] = new_item(empty
, empty_desc
);
82 if (vl
->empty
[0] == NULL
) {
86 vl
->window
= newwin(nlines
, ncols
, begin_y
, begin_x
);
87 if (vl
->window
== NULL
) {
90 vl
->panel
= new_panel(vl
->window
);
91 if (vl
->panel
== NULL
) {
95 vl
->menu
= new_menu(vl
->empty
);
96 if (vl
->menu
== NULL
) {
100 set_menu_format(vl
->menu
, nlines
, 1);
101 set_menu_win(vl
->menu
, vl
->window
);
103 menu_opts_on(vl
->menu
, O_SHOWDESC
);
104 set_menu_mark(vl
->menu
, "* ");
114 void value_list_resize(struct value_list
*vl
, int nlines
, int ncols
,
115 int begin_y
, int begin_x
)
119 unpost_menu(vl
->menu
);
120 nwin
= newwin(nlines
, ncols
, begin_y
, begin_x
);
121 replace_panel(vl
->panel
, nwin
);
124 set_menu_format(vl
->menu
, nlines
, 1);
125 set_menu_win(vl
->menu
, vl
->window
);
129 static uint32_t get_num_values(TALLOC_CTX
*ctx
, const struct registry_key
*key
)
131 const char *classname
;
132 uint32_t num_subkeys
;
134 NTTIME last_change_time
;
135 uint32_t max_subkeynamelen
;
136 uint32_t max_valnamelen
;
137 uint32_t max_valbufsize
;
140 rv
= reg_key_get_info(ctx
, key
, &classname
, &num_subkeys
,
141 &num_values
, &last_change_time
,
142 &max_subkeynamelen
, &max_valnamelen
,
145 if (W_ERROR_IS_OK(rv
)) {
152 void value_list_show(struct value_list
*vl
)
157 static bool string_is_printable(const char *s
)
161 for (p
= s
; *p
; ++p
) {
170 static WERROR
append_data_summary(struct value_item
*vitem
)
174 /* This is adapted from print_registry_value() in net_registry_util.c */
176 switch(vitem
->type
) {
179 if (vitem
->data
.length
>= 4) {
180 v
= IVAL(vitem
->data
.data
, 0);
182 tmp
= talloc_asprintf_append(vitem
->value_desc
, "(0x%x)", v
);
186 case REG_EXPAND_SZ
: {
189 if (!pull_reg_sz(vitem
, &vitem
->data
, &s
)) {
192 vitem
->unprintable
= !string_is_printable(s
);
193 if (vitem
->unprintable
) {
194 tmp
= talloc_asprintf_append(vitem
->value_desc
,
197 tmp
= talloc_asprintf_append(vitem
->value_desc
,
206 if (!pull_reg_multi_sz(vitem
, &vitem
->data
, &a
)) {
209 tmp
= vitem
->value_desc
;
210 for (i
= 0; a
[i
] != NULL
; ++i
) {
211 if (!string_is_printable(a
[i
])) {
212 tmp
= talloc_asprintf_append(tmp
,
214 vitem
->unprintable
= true;
216 tmp
= talloc_asprintf_append(tmp
, "\"%s\" ",
226 tmp
= talloc_asprintf_append(vitem
->value_desc
, "(%d bytes)",
227 (int)vitem
->data
.length
);
230 tmp
= talloc_asprintf_append(vitem
->value_desc
,
239 vitem
->value_desc
= tmp
;
244 WERROR
value_list_load(struct value_list
*vl
, struct registry_key
*key
)
248 struct value_item
*vitem
;
251 static const char *empty_name
= "(empty)";
254 unpost_menu(vl
->menu
);
256 n_values
= get_num_values(vl
, key
);
258 set_menu_items(vl
->menu
, vl
->empty
);
262 new_items
= talloc_zero_array(vl
, ITEM
*, n_values
+ 1);
263 if (new_items
== NULL
) {
267 for (idx
= 0; idx
< n_values
; ++idx
) {
268 vitem
= talloc_zero(new_items
, struct value_item
);
273 rv
= reg_key_get_value_by_index(vitem
, key
, idx
,
278 if (!W_ERROR_IS_OK(rv
)) {
283 vitem
->value_desc
= talloc_asprintf(vitem
, "%-14s",
284 str_regtype(vitem
->type
));
285 if (vitem
->value_desc
== NULL
) {
290 rv
= append_data_summary(vitem
);
291 if (!W_ERROR_IS_OK(rv
)) {
296 /* ncurses won't accept empty strings in menu items */
297 name
= vitem
->value_name
;
298 if (name
[0] == '\0') {
301 new_items
[idx
] = new_item(name
, vitem
->value_desc
);
302 if (new_items
[idx
] == NULL
) {
307 set_item_userptr(new_items
[idx
], vitem
);
310 set_menu_items(vl
->menu
, new_items
);
311 value_list_free_items(vl
->items
);
312 vl
->items
= new_items
;