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

Richard W.M. Jones rjones at redhat.com
Tue Jan 19 13:43:33 UTC 2010


This patch should not change behaviour for existing clients.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
-------------- next part --------------
>From 2775c947aa502a4ef5023315294147018778ae2d 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 6/7] 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 (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 (t != hive_t_binary) {
+          ret = skip_bad ? 0 : -1;
+          goto error;
+        }
+        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