[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH 2/7] hivex: Split value_key function into value_key and value_key_len



This function breaks the value name calculation out so the name does
not need to be fetched and immediately thrown away when one only needs
the name.

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

diff --git a/generator/generator.ml b/generator/generator.ml
index 8bd944d..48b6e3a 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -229,6 +229,17 @@ string C<\"\"> here.  The default key is often written C<\"@\">, but
 inside hives that has no meaning and won't give you the
 default key.";
 
+  "value_key_len", (RSize, [AHive; AValue "val"]),
+    "return the length of a value's key",
+    "\
+Return the length of the key (name) of a (key, value) pair.  The
+length can legitimately be 0, so errno is the necesary mechanism
+to check for errors.
+
+In the context of Windows Registries, a zero-length name means
+that this value is the default key for this node in the tree.
+This is usually written as C<\"@\">.";
+
   "value_key", (RString, [AHive; AValue "val"]),
     "return the key of a (key, value) pair",
     "\
diff --git a/lib/hivex.c b/lib/hivex.c
index 4b9fcf0..61177d3 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -1189,8 +1189,8 @@ hivex_node_get_value (hive_h *h, hive_node_h node, const char *key)
   return ret;
 }
 
-char *
-hivex_value_key (hive_h *h, hive_value_h value)
+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")) {
     errno = EINVAL;
@@ -1199,23 +1199,38 @@ hivex_value_key (hive_h *h, hive_value_h value)
 
   struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
 
-  /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
-   * necessary.  However we do need to nul-terminate the string.
-   */
-
   /* vk->name_len is unsigned, 16 bit, so this is safe ...  However
    * we have to make sure the length doesn't exceed the block length.
    */
-  size_t len = le16toh (vk->name_len);
+  size_t ret = le16toh (vk->name_len);
   size_t seg_len = block_len (h, value, NULL);
-  if (sizeof (struct ntreg_vk_record) + len - 1 > seg_len) {
+  if (sizeof (struct ntreg_vk_record) + ret - 1 > seg_len) {
     if (h->msglvl >= 2)
-      fprintf (stderr, "hivex_value_key: returning EFAULT"
+      fprintf (stderr, "hivex_value_key_len: returning EFAULT"
                " because key length is too long (%zu, %zu)\n",
-               len, seg_len);
+               ret, seg_len);
     errno = EFAULT;
-    return NULL;
+    return 0;
   }
+  return ret;
+}
+
+char *
+hivex_value_key (hive_h *h, hive_value_h value)
+{
+  if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+    errno = EINVAL;
+    return 0;
+  }
+
+  struct ntreg_vk_record *vk = (struct ntreg_vk_record *) (h->addr + value);
+
+  /* AFAIK the key is always plain ASCII, so no conversion to UTF-8 is
+   * necessary.  However we do need to nul-terminate the string.
+   */
+  size_t len = hivex_value_key_len (h, value);
+  if (errno != 0)
+    return NULL;
 
   char *ret = malloc (len + 1);
   if (ret == NULL)
-- 
1.7.6




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]