/* Very inefficient, but at least having a separate API call * allows us to make it more efficient in future. */ hive_value_h hivex_node_get_value (hive_h *h, hive_node_h node, const char *key) { hive_value_h *values = NULL; char *name = NULL; hive_value_h ret = 0; values = hivex_node_values (h, node); if (!values) goto error; size_t i; for (i = 0; values[i] != 0; ++i) { name = hivex_value_key (h, values[i]); if (!name) goto error; if (STRCASEEQ (name, key)) { ret = values[i]; break; } free (name); name = NULL; } error: free (values); free (name); return ret; }
guestfs_int_hivex_value_list * do_hivex_node_values (int64_t nodeh) { guestfs_int_hivex_value_list *ret; CLEANUP_FREE hive_value_h *r = NULL; size_t i, len; NEED_HANDLE (NULL); r = hivex_node_values (h, nodeh); if (r == NULL) { reply_with_perror ("failed"); return NULL; } len = 0; for (i = 0; r[i] != 0; ++i) len++; ret = malloc (sizeof *ret); if (!ret) { reply_with_perror ("malloc"); return NULL; } ret->guestfs_int_hivex_value_list_len = len; ret->guestfs_int_hivex_value_list_val = malloc (len * sizeof (guestfs_int_hivex_value)); if (ret->guestfs_int_hivex_value_list_val == NULL) { reply_with_perror ("malloc"); free (ret); return NULL; } for (i = 0; i < len; ++i) ret->guestfs_int_hivex_value_list_val[i].hivex_value_h = (int64_t) r[i]; return ret; }
static PyObject * py_hivex_node_values (PyObject *self, PyObject *args) { PyObject *py_r; hive_value_h *r; hive_h *h; PyObject *py_h; long node; if (!PyArg_ParseTuple (args, (char *) "Ol:hivex_node_values", &py_h, &node)) return NULL; h = get_handle (py_h); r = hivex_node_values (h, node); if (r == NULL) { PyErr_SetString (PyExc_RuntimeError, strerror (errno)); return NULL; } py_r = put_node_list (r); free (r); return py_r; }
int hivex_node_set_value (hive_h *h, hive_node_h node, const hive_set_value *val, int flags) { int retval = -1; hive_value_h *prev_values; hive_set_value *new_values; size_t nr_values; size_t i; ssize_t idx_of_val; prev_values = hivex_node_values (h, node); if (prev_values == NULL) return -1; /* Count number of existing values in this node. */ nr_values = 0; for (i = 0; prev_values[i] != 0; i++) nr_values++; /* Allocate a new hive_set_value list, with space for all existing * values, plus 1 (for the new key if we're not replacing an * existing key). */ new_values = calloc (nr_values + 1, sizeof (hive_set_value)); if (new_values == NULL) goto out1; /* Copy the old values to the new values. If we find the key along * the way, note its index in 'idx_of_val'. */ idx_of_val = -1; for (i = 0; prev_values[i] != 0; i++) { size_t len; hive_type t; char *valkey, *valval; valval = hivex_value_value (h, prev_values[i], &t, &len); if (valval == NULL) goto out2; new_values[i].value = valval; new_values[i].t = t; new_values[i].len = len; valkey = hivex_value_key (h, prev_values[i]); if (valkey == NULL) goto out2; new_values[i].key = valkey; if (STRCASEEQ (valkey, val->key)) idx_of_val = i; } if (idx_of_val > -1) { free (new_values[idx_of_val].key); free (new_values[idx_of_val].value); } else { /* insert it at the end */ idx_of_val = nr_values; nr_values++; } new_values[idx_of_val].key = strdup (val->key); new_values[idx_of_val].value = malloc (val->len); new_values[idx_of_val].len = val->len; new_values[idx_of_val].t = val->t; if (new_values[idx_of_val].key == NULL || new_values[idx_of_val].value == NULL) goto out2; memcpy (new_values[idx_of_val].value, val->value, val->len); retval = hivex_node_set_values (h, node, nr_values, new_values, 0); out2: for (i = 0; i < nr_values; ++i) { free (new_values[i].key); free (new_values[i].value); } free (new_values); out1: free (prev_values); return retval; }