[Libguestfs] [PATCH 4/7] hivex: Add metadata length functions for nodes and values

Alex Nelson ajnelson at cs.ucsc.edu
Fri Sep 2 01:17:36 UTC 2011


This patch adds hivex_node_struct_length and hivex_value_struct_length
to the hivex ABI, to report the amount of hive space used for each
stored structure.

Signed-off-by: Alex Nelson <ajnelson at cs.ucsc.edu>
---
 generator/generator.ml |   12 ++++++++++++
 lib/hivex.c            |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/generator/generator.ml b/generator/generator.ml
index 15ebc44..5a71930 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -264,6 +264,18 @@ information, and the value itself.  Also, C<hivex_value_*> functions
 below which can be used to return the value in a more useful form when
 you know the type in advance.";
 
+  "node_struct_length", (RSize, [AHive; ANode "node"]),
+    "return the length of a node",
+    "\
+Return the length of the node data structure.  Returns 0
+and sets errno on error.";
+
+  "value_struct_length", (RSize, [AHive; AValue "val"]),
+    "return the length of a value data structure",
+    "\
+Return the length of the value data structure.  Returns 0
+and sets errno on error.";
+
   "value_value", (RLenTypeVal, [AHive; AValue "val"]),
     "return data length, data type and data of a value",
     "\
diff --git a/lib/hivex.c b/lib/hivex.c
index 61177d3..d8ffa63 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -585,6 +585,30 @@ hivex_root (hive_h *h)
   return ret;
 }
 
+size_t
+hivex_node_struct_length (hive_h *h, hive_node_h node)
+{
+  if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+    errno = EINVAL;
+    return 0;
+  }
+
+  struct ntreg_nk_record *nk = (struct ntreg_nk_record *) (h->addr + node);
+  size_t name_len = le16toh (nk->name_len);
+  /* -1 to avoid double-counting the first name character */
+  size_t ret = name_len + sizeof (struct ntreg_nk_record) - 1;
+  int used;
+  size_t seg_len = block_len (h, node, &used);
+  if (ret > seg_len) {
+    if (h->msglvl >= 2)
+      fprintf (stderr, "hivex_node_struct_length: returning EFAULT because"
+               " node name is too long (%zu, %zu)\n", name_len, seg_len);
+    errno = EFAULT;
+    return 0;
+  }
+  return ret;
+}
+
 char *
 hivex_node_name (hive_h *h, hive_node_h node)
 {
@@ -1190,6 +1214,15 @@ hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
 }
 
 size_t
+hivex_value_struct_length (hive_h *h, hive_value_h value) {
+  size_t key_len = hivex_value_key_len (h, value);
+  if (errno)
+    return 0;
+  /* -1 to avoid double-counting the first name character */
+  return key_len + sizeof (struct ntreg_vk_record) - 1;
+}
+
+size_t
 hivex_value_key_len (hive_h *h, hive_value_h value)
 {
   if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
-- 
1.7.6






More information about the Libguestfs mailing list