Add test hive and generator script
[hivex.git] / xml / hivexml.c
index 2967ac9..54d9049 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 #include <time.h>
+#include <locale.h>
+
+#ifdef HAVE_LIBINTL_H
+#include <libintl.h>
+#endif
+
+#include <getopt.h>
 
 #include <libxml/xmlwriter.h>
 
@@ -79,8 +86,10 @@ int
 main (int argc, char *argv[])
 {
   setlocale (LC_ALL, "");
+#ifdef HAVE_BINDTEXTDOMAIN
   bindtextdomain (PACKAGE, LOCALEBASEDIR);
   textdomain (PACKAGE);
+#endif
 
   int c;
   int open_flags = 0;
@@ -162,6 +171,10 @@ main (int argc, char *argv[])
  * fiwalk.cpp.
  *
  * The caller should free the returned buffer.
+ *
+ * This function returns NULL on a 0 input.  In the context of
+ * hives, which only have mtimes, 0 will always be a complete
+ * absence of data.
  */
 
 #define WINDOWS_TICK 10000000LL
@@ -175,6 +188,9 @@ filetime_to_8601 (int64_t windows_ticks)
   time_t t;
   struct tm *tm;
 
+  if (windows_ticks == 0LL)
+    return NULL;
+
   t = windows_ticks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH;
   tm = gmtime (&t);
   if (tm == NULL)
@@ -204,6 +220,10 @@ node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name)
   XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "node"));
   XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "name", BAD_CAST name));
 
+  if (node == hivex_root (h)) {
+    XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "root", BAD_CAST "1"));
+  }
+
   last_modified = hivex_node_timestamp (h, node);
   if (last_modified >= 0) {
     timebuf = filetime_to_8601 (last_modified);
@@ -274,7 +294,9 @@ value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
   }
 
   start_value (writer, key, type, NULL);
+  XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
   XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST str));
+  XML_CHECK (xmlTextWriterEndAttribute, (writer));
   end_value (writer);
   return 0;
 }
@@ -328,7 +350,9 @@ value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node,
   }
 
   start_value (writer, key, type, "base64");
+  XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
   XML_CHECK (xmlTextWriterWriteBase64, (writer, str, 0, len));
+  XML_CHECK (xmlTextWriterEndAttribute, (writer));
   end_value (writer);
 
   return 0;
@@ -340,7 +364,7 @@ value_dword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
 {
   xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
   start_value (writer, key, "int32", NULL);
-  XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi32, v));
+  XML_CHECK (xmlTextWriterWriteFormatAttribute, (writer, BAD_CAST "value", "%" PRIi32, v));
   end_value (writer);
   return 0;
 }
@@ -351,7 +375,7 @@ value_qword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
 {
   xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
   start_value (writer, key, "int64", NULL);
-  XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi64, v));
+  XML_CHECK (xmlTextWriterWriteFormatAttribute, (writer, BAD_CAST "value", "%" PRIi64, v));
   end_value (writer);
   return 0;
 }
@@ -362,7 +386,9 @@ value_binary (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
 {
   xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
   start_value (writer, key, "binary", "base64");
+  XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
   XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
+  XML_CHECK (xmlTextWriterEndAttribute, (writer));
   end_value (writer);
   return 0;
 }
@@ -373,7 +399,11 @@ value_none (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
 {
   xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
   start_value (writer, key, "none", "base64");
-  if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
+  if (len > 0) {
+    XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
+    XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
+    XML_CHECK (xmlTextWriterEndAttribute, (writer));
+  }
   end_value (writer);
   return 0;
 }
@@ -406,7 +436,11 @@ value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
   }
 
   start_value (writer, key, type, "base64");
-  if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
+  if (len > 0) {
+    XML_CHECK (xmlTextWriterStartAttribute, (writer, BAD_CAST "value"));
+    XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
+    XML_CHECK (xmlTextWriterEndAttribute, (writer));
+  }
   end_value (writer);
 
   return 0;