From: "Richard W.M. Jones" <rjones(a)redhat.com>
Although this change seems rather large, including removing a large
block of dead code, there should be no functional change.
---
lib/node.c | 122 +++++++++++++++++++++++++++----------------------------------
1 file changed, 54 insertions(+), 68 deletions(-)
diff --git a/lib/node.c b/lib/node.c
index 1255a84..91c85e6 100644
--- a/lib/node.c
+++ b/lib/node.c
@@ -184,6 +184,10 @@ hivex_node_classname (hive_h *h, hive_node_h node)
}
#endif
+static int _get_children (hive_h *h, hive_node_h blkoff,
+ offset_list *children, offset_list *blocks,
+ int flags);
+
/* Iterate over children (ie. subkeys of a node), returning child
* nodes and intermediate blocks.
*
@@ -255,11 +259,45 @@ _hivex_get_children (hive_h *h, hive_node_h node,
goto error;
}
- if (_hivex_add_to_offset_list (&blocks, subkey_lf) == -1)
+ if (_get_children (h, subkey_lf, &children, &blocks, flags) == -1)
goto error;
+ /* Check the number of children we ended up reading matches
+ * nr_subkeys_in_nk.
+ */
+ size_t nr_children = _hivex_get_offset_list_length (&children);
+ if (nr_subkeys_in_nk != nr_children) {
+ SET_ERRNO (ENOTSUP,
+ "nr_subkeys_in_nk = %zu "
+ "is not equal to number of children read %zu",
+ nr_subkeys_in_nk, nr_children);
+ goto error;
+ }
+
+ out:
+ *children_ret = _hivex_return_offset_list (&children);
+ *blocks_ret = _hivex_return_offset_list (&blocks);
+ if (!*children_ret || !*blocks_ret)
+ goto error;
+ return 0;
+
+ error:
+ _hivex_free_offset_list (&children);
+ _hivex_free_offset_list (&blocks);
+ return -1;
+}
+
+static int
+_get_children (hive_h *h, hive_node_h blkoff,
+ offset_list *children, offset_list *blocks,
+ int flags)
+{
+ /* Add this intermediate block. */
+ if (_hivex_add_to_offset_list (blocks, blkoff) == -1)
+ return -1;
+
struct ntreg_hbin_block *block =
- (struct ntreg_hbin_block *) ((char *) h->addr + subkey_lf);
+ (struct ntreg_hbin_block *) ((char *) h->addr + blkoff);
/* Points to lf-record? (Note, also "lh" but that is basically the
* same as "lf" as far as we are concerned here).
@@ -272,17 +310,10 @@ _hivex_get_children (hive_h *h, hive_node_h node,
*/
size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
- if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
- SET_ERRNO (ENOTSUP,
- "nr_subkeys_in_nk = %zu is not equal to nr_subkeys_in_lf =
%zu",
- nr_subkeys_in_nk, nr_subkeys_in_lf);
- goto error;
- }
-
- size_t len = block_len (h, subkey_lf, NULL);
+ size_t len = block_len (h, blkoff, NULL);
if (8 + nr_subkeys_in_lf * 8 > len) {
SET_ERRNO (EFAULT, "too many subkeys (%zu, %zu)", nr_subkeys_in_lf,
len);
- goto error;
+ return -1;
}
size_t i;
@@ -292,11 +323,11 @@ _hivex_get_children (hive_h *h, hive_node_h node,
if (!(flags & GET_CHILDREN_NO_CHECK_NK)) {
if (!IS_VALID_BLOCK (h, subkey)) {
SET_ERRNO (EFAULT, "subkey is not a valid block (0x%zx)", subkey);
- goto error;
+ return -1;
}
}
- if (_hivex_add_to_offset_list (&children, subkey) == -1)
- goto error;
+ if (_hivex_add_to_offset_list (children, subkey) == -1)
+ return -1;
}
}
/* Points to ri-record? */
@@ -305,14 +336,14 @@ _hivex_get_children (hive_h *h, hive_node_h node,
size_t nr_offsets = le16toh (ri->nr_offsets);
- /* Count total number of children. */
- size_t i, count = 0;
+ /* Copy list of children. */
+ size_t i;
for (i = 0; i < nr_offsets; ++i) {
hive_node_h offset = le32toh (ri->offset[i]);
offset += 0x1000;
if (!IS_VALID_BLOCK (h, offset)) {
SET_ERRNO (EFAULT, "ri-offset is not a valid block (0x%zx)", offset);
- goto error;
+ return -1;
}
if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset,
"lh")) {
struct ntreg_lf_record *block =
@@ -320,42 +351,7 @@ _hivex_get_children (hive_h *h, hive_node_h node,
SET_ERRNO (ENOTSUP,
"ri-record offset does not point to lf/lh (0x%zx, %d, %d)",
offset, block->id[0], block->id[1]);
- goto error;
- }
-
- if (_hivex_add_to_offset_list (&blocks, offset) == -1)
- goto error;
-
- struct ntreg_lf_record *lf =
- (struct ntreg_lf_record *) ((char *) h->addr + offset);
-
- count += le16toh (lf->nr_keys);
- }
-
- if (nr_subkeys_in_nk != count) {
- SET_ERRNO (ENOTSUP,
- "nr_subkeys_in_nk = %zu is not equal to counted = %zu",
- nr_subkeys_in_nk, count);
- goto error;
- }
-
- /* Copy list of children. Note nr_subkeys_in_nk is limited to
- * something reasonable above.
- */
- for (i = 0; i < nr_offsets; ++i) {
- hive_node_h offset = le32toh (ri->offset[i]);
- offset += 0x1000;
- if (!IS_VALID_BLOCK (h, offset)) {
- SET_ERRNO (EFAULT, "ri-offset is not a valid block (0x%zx)", offset);
- goto error;
- }
- if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset,
"lh")) {
- struct ntreg_lf_record *block =
- (struct ntreg_lf_record *) ((char *) h->addr + offset);
- SET_ERRNO (ENOTSUP,
- "ri-record offset does not point to lf/lh (0x%zx, %d, %d)",
- offset, block->id[0], block->id[1]);
- goto error;
+ return -1;
}
struct ntreg_lf_record *lf =
@@ -370,32 +366,22 @@ _hivex_get_children (hive_h *h, hive_node_h node,
SET_ERRNO (EFAULT,
"indirect subkey is not a valid block (0x%zx)",
subkey);
- goto error;
+ return -1;
}
}
- if (_hivex_add_to_offset_list (&children, subkey) == -1)
- goto error;
+ if (_hivex_add_to_offset_list (children, subkey) == -1)
+ return -1;
}
}
}
else {
SET_ERRNO (ENOTSUP,
"subkey block is not lf/lh/ri (0x%zx, %d, %d)",
- subkey_lf, block->id[0], block->id[1]);
- goto error;
+ blkoff, block->id[0], block->id[1]);
+ return -1;
}
- out:
- *children_ret = _hivex_return_offset_list (&children);
- *blocks_ret = _hivex_return_offset_list (&blocks);
- if (!*children_ret || !*blocks_ret)
- goto error;
return 0;
-
- error:
- _hivex_free_offset_list (&children);
- _hivex_free_offset_list (&blocks);
- return -1;
}
hive_node_h *
--
1.8.3.1