[Libguestfs] [PATCH 6/13] hivex: Add value_any callback to the visitor.

Richard W.M. Jones rjones at redhat.com
Thu Jan 28 10:18:21 UTC 2010


-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
-------------- next part --------------
>From 83f27fdbca43dba3706c3c7b21f113dfa2bbf946 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Tue, 19 Jan 2010 10:06:00 +0000
Subject: [PATCH 06/13] hivex: Add value_any callback to the visitor.

The visitor currently contains lots of value_* callbacks, such as
value_string which is called back when the value has type string.

This is fine but it makes it complicated to deal with the case where
you just want to see 'a value', and don't care about its type.

The value_any callback allows visitors to see values generically.
---
 hivex/hivex.c   |  178 +++++++++++++++++++++++++++++--------------------------
 hivex/hivex.h   |    1 +
 hivex/hivex.pod |    5 ++
 3 files changed, 101 insertions(+), 83 deletions(-)

diff --git a/hivex/hivex.c b/hivex/hivex.c
index cb6fc62..81d217b 100644
--- a/hivex/hivex.c
+++ b/hivex/hivex.c
@@ -1421,114 +1421,126 @@ hivex__visit_node (hive_h *h, hive_node_h node,
       goto error;
     }
 
-    switch (t) {
-    case hive_t_none:
+    if (vtor->value_any) {
       str = hivex_value_value (h, values[i], &t, &len);
       if (str == NULL) {
         ret = skip_bad ? 0 : -1;
         goto error;
       }
-      if (t != hive_t_none) {
-        ret = skip_bad ? 0 : -1;
-        goto error;
-      }
-      if (vtor->value_none &&
-          vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
+      if (vtor->value_any (h, opaque, node, values[i], t, len, key, str) == -1)
         goto error;
       free (str); str = NULL;
-      break;
-
-    case hive_t_string:
-    case hive_t_expand_string:
-    case hive_t_link:
-      str = hivex_value_string (h, values[i]);
-      if (str == NULL) {
-        if (errno != EILSEQ && errno != EINVAL) {
+    }
+    else {
+      switch (t) {
+      case hive_t_none:
+        str = hivex_value_value (h, values[i], &t, &len);
+        if (str == NULL) {
           ret = skip_bad ? 0 : -1;
           goto error;
         }
-        if (vtor->value_string_invalid_utf16) {
-          str = hivex_value_value (h, values[i], &t, &len);
-          if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
-            goto error;
-          free (str); str = NULL;
+        if (t != hive_t_none) {
+          ret = skip_bad ? 0 : -1;
+          goto error;
         }
+        if (vtor->value_none &&
+            vtor->value_none (h, opaque, node, values[i], t, len, key, str) == -1)
+          goto error;
+        free (str); str = NULL;
         break;
-      }
-      if (vtor->value_string &&
-          vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
-        goto error;
-      free (str); str = NULL;
-      break;
 
-    case hive_t_dword:
-    case hive_t_dword_be: {
-      int32_t i32 = hivex_value_dword (h, values[i]);
-      if (vtor->value_dword &&
-          vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
-        goto error;
-      break;
-    }
-
-    case hive_t_qword: {
-      int64_t i64 = hivex_value_qword (h, values[i]);
-      if (vtor->value_qword &&
-          vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
-        goto error;
-      break;
-    }
+      case hive_t_string:
+      case hive_t_expand_string:
+      case hive_t_link:
+        str = hivex_value_string (h, values[i]);
+        if (str == NULL) {
+          if (errno != EILSEQ && errno != EINVAL) {
+            ret = skip_bad ? 0 : -1;
+            goto error;
+          }
+          if (vtor->value_string_invalid_utf16) {
+            str = hivex_value_value (h, values[i], &t, &len);
+            if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
+              goto error;
+            free (str); str = NULL;
+          }
+          break;
+        }
+        if (vtor->value_string &&
+            vtor->value_string (h, opaque, node, values[i], t, len, key, str) == -1)
+          goto error;
+        free (str); str = NULL;
+        break;
 
-    case hive_t_binary:
-      str = hivex_value_value (h, values[i], &t, &len);
-      if (str == NULL) {
-        ret = skip_bad ? 0 : -1;
-        goto error;
+      case hive_t_dword:
+      case hive_t_dword_be: {
+        int32_t i32 = hivex_value_dword (h, values[i]);
+        if (vtor->value_dword &&
+            vtor->value_dword (h, opaque, node, values[i], t, len, key, i32) == -1)
+          goto error;
+        break;
       }
-      if (t != hive_t_binary) {
-        ret = skip_bad ? 0 : -1;
-        goto error;
+
+      case hive_t_qword: {
+        int64_t i64 = hivex_value_qword (h, values[i]);
+        if (vtor->value_qword &&
+            vtor->value_qword (h, opaque, node, values[i], t, len, key, i64) == -1)
+          goto error;
+        break;
       }
-      if (vtor->value_binary &&
-          vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
-        goto error;
-      free (str); str = NULL;
-      break;
 
-    case hive_t_multiple_strings:
-      strs = hivex_value_multiple_strings (h, values[i]);
-      if (strs == NULL) {
-        if (errno != EILSEQ && errno != EINVAL) {
+      case hive_t_binary:
+        str = hivex_value_value (h, values[i], &t, &len);
+        if (str == NULL) {
+          ret = skip_bad ? 0 : -1;
+          goto error;
+        }
+        if (t != hive_t_binary) {
           ret = skip_bad ? 0 : -1;
           goto error;
         }
-        if (vtor->value_string_invalid_utf16) {
-          str = hivex_value_value (h, values[i], &t, &len);
-          if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
+        if (vtor->value_binary &&
+            vtor->value_binary (h, opaque, node, values[i], t, len, key, str) == -1)
+          goto error;
+        free (str); str = NULL;
+        break;
+
+      case hive_t_multiple_strings:
+        strs = hivex_value_multiple_strings (h, values[i]);
+        if (strs == NULL) {
+          if (errno != EILSEQ && errno != EINVAL) {
+            ret = skip_bad ? 0 : -1;
             goto error;
-          free (str); str = NULL;
+          }
+          if (vtor->value_string_invalid_utf16) {
+            str = hivex_value_value (h, values[i], &t, &len);
+            if (vtor->value_string_invalid_utf16 (h, opaque, node, values[i], t, len, key, str) == -1)
+              goto error;
+            free (str); str = NULL;
+          }
+          break;
         }
+        if (vtor->value_multiple_strings &&
+            vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
+          goto error;
+        free_strings (strs); strs = NULL;
         break;
-      }
-      if (vtor->value_multiple_strings &&
-          vtor->value_multiple_strings (h, opaque, node, values[i], t, len, key, strs) == -1)
-        goto error;
-      free_strings (strs); strs = NULL;
-      break;
 
-    case hive_t_resource_list:
-    case hive_t_full_resource_description:
-    case hive_t_resource_requirements_list:
-    default:
-      str = hivex_value_value (h, values[i], &t, &len);
-      if (str == NULL) {
-        ret = skip_bad ? 0 : -1;
-        goto error;
+      case hive_t_resource_list:
+      case hive_t_full_resource_description:
+      case hive_t_resource_requirements_list:
+      default:
+        str = hivex_value_value (h, values[i], &t, &len);
+        if (str == NULL) {
+          ret = skip_bad ? 0 : -1;
+          goto error;
+        }
+        if (vtor->value_other &&
+            vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
+          goto error;
+        free (str); str = NULL;
+        break;
       }
-      if (vtor->value_other &&
-          vtor->value_other (h, opaque, node, values[i], t, len, key, str) == -1)
-        goto error;
-      free (str); str = NULL;
-      break;
     }
 
     free (key); key = NULL;
diff --git a/hivex/hivex.h b/hivex/hivex.h
index b0c1c3b..56718b4 100644
--- a/hivex/hivex.h
+++ b/hivex/hivex.h
@@ -102,6 +102,7 @@ struct hivex_visitor {
   int (*value_binary) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
   int (*value_none) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
   int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
+  int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
 };
 
 #define HIVEX_VISIT_SKIP_BAD 1
diff --git a/hivex/hivex.pod b/hivex/hivex.pod
index 0de4d54..5a58144 100644
--- a/hivex/hivex.pod
+++ b/hivex/hivex.pod
@@ -288,6 +288,11 @@ all, set the function pointer to NULL.
          hive_type t, size_t len, const char *key, const char *value);
    int (*value_other) (hive_h *, void *opaque, hive_node_h, hive_value_h,
          hive_type t, size_t len, const char *key, const char *value);
+   /* If value_any callback is not NULL, then the other value_*
+    * callbacks are not used, and value_any is called on all values.
+    */
+   int (*value_any) (hive_h *, void *opaque, hive_node_h, hive_value_h,
+         hive_type t, size_t len, const char *key, const char *value);
  };
 
 =over 4
-- 
1.6.5.2



More information about the Libguestfs mailing list