hivex: Split value_key function into value_key and value_key_len
authorAlex Nelson <ajnelson@cs.ucsc.edu>
Fri, 2 Sep 2011 01:17:27 +0000 (18:17 -0700)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 6 Sep 2011 13:58:01 +0000 (14:58 +0100)
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>
RWMJ fixed hivex_value_key handling of errno.

generator/generator.ml
lib/hivex.c

index b880b48..6f318ac 100755 (executable)
@@ -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",
     "\
index 4b9fcf0..a183527 100644 (file)
@@ -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,39 @@ 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.
+   */
+  errno = 0;
+  size_t len = hivex_value_key_len (h, value);
+  if (len == 0 && errno != 0)
+    return NULL;
 
   char *ret = malloc (len + 1);
   if (ret == NULL)