1 /* hivexml - Convert Windows Registry "hive" to XML file.
2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <libxml/xmlwriter.h>
31 /* Callback functions. */
32 static int node_start (hive_h *, void *, hive_node_h, const char *name);
33 static int node_end (hive_h *, void *, hive_node_h, const char *name);
34 static int value_string (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *str);
35 static int value_multiple_strings (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, char **argv);
36 static int value_string_invalid_utf16 (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *str);
37 static int value_dword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t);
38 static int value_qword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t);
39 static int value_binary (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
40 static int value_none (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
41 static int value_other (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, const char *value);
43 static struct hivex_visitor visitor = {
44 .node_start = node_start,
46 .value_string = value_string,
47 .value_multiple_strings = value_multiple_strings,
48 .value_string_invalid_utf16 = value_string_invalid_utf16,
49 .value_dword = value_dword,
50 .value_qword = value_qword,
51 .value_binary = value_binary,
52 .value_none = value_none,
53 .value_other = value_other
56 #define XML_CHECK(proc, args) \
58 if ((proc args) == -1) { \
59 fprintf (stderr, "%s: failed to write XML document\n", #proc); \
65 main (int argc, char *argv[])
71 while ((c = getopt (argc, argv, "dk")) != EOF) {
74 open_flags |= HIVEX_OPEN_DEBUG;
77 visit_flags |= HIVEX_VISIT_SKIP_BAD;
80 fprintf (stderr, "hivexml [-dk] regfile > output.xml\n");
85 if (optind + 1 != argc) {
86 fprintf (stderr, "hivexml: missing name of input file\n");
90 hive_h *h = hivex_open (argv[optind], open_flags);
92 perror (argv[optind]);
96 /* Note both this macro, and xmlTextWriterStartDocument leak memory. There
97 * doesn't seem to be any way to recover that memory, but it's not a
102 xmlTextWriterPtr writer;
103 writer = xmlNewTextWriterFilename ("/dev/stdout", 0);
104 if (writer == NULL) {
105 fprintf (stderr, "xmlNewTextWriterFilename: failed to create XML writer\n");
109 XML_CHECK (xmlTextWriterStartDocument, (writer, NULL, "utf-8", NULL));
110 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "hive"));
112 if (hivex_visit (h, &visitor, sizeof visitor, writer, visit_flags) == -1) {
113 perror (argv[optind]);
117 if (hivex_close (h) == -1) {
118 perror (argv[optind]);
122 XML_CHECK (xmlTextWriterEndElement, (writer));
123 XML_CHECK (xmlTextWriterEndDocument, (writer));
124 xmlFreeTextWriter (writer);
130 node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name)
132 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
133 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "node"));
134 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "name", BAD_CAST name));
139 node_end (hive_h *h, void *writer_v, hive_node_h node, const char *name)
141 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
142 XML_CHECK (xmlTextWriterEndElement, (writer));
147 start_value (xmlTextWriterPtr writer,
148 const char *key, const char *type, const char *encoding)
150 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "value"));
151 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "type", BAD_CAST type));
153 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "encoding", BAD_CAST encoding));
155 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "key", BAD_CAST key));
156 else /* default key */
157 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "default", BAD_CAST "1"));
161 end_value (xmlTextWriterPtr writer)
163 XML_CHECK (xmlTextWriterEndElement, (writer));
167 value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
168 hive_type t, size_t len, const char *key, const char *str)
170 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
174 case hive_t_string: type = "string"; break;
175 case hive_t_expand_string: type = "expand"; break;
176 case hive_t_link: type = "link"; break;
181 case hive_t_dword_be:
182 case hive_t_multiple_strings:
183 case hive_t_resource_list:
184 case hive_t_full_resource_description:
185 case hive_t_resource_requirements_list:
187 abort (); /* internal error - should not happen */
193 start_value (writer, key, type, NULL);
194 XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST str));
200 value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node,
201 hive_value_h value, hive_type t, size_t len,
202 const char *key, char **argv)
204 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
205 start_value (writer, key, "string-list", NULL);
208 for (i = 0; argv[i] != NULL; ++i) {
209 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "string"));
210 XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST argv[i]));
211 XML_CHECK (xmlTextWriterEndElement, (writer));
219 value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node,
220 hive_value_h value, hive_type t, size_t len,
222 const char *str /* original data */)
224 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
228 case hive_t_string: type = "bad-string"; break;
229 case hive_t_expand_string: type = "bad-expand"; break;
230 case hive_t_link: type = "bad-link"; break;
231 case hive_t_multiple_strings: type = "bad-string-list"; break;
236 case hive_t_dword_be:
237 case hive_t_resource_list:
238 case hive_t_full_resource_description:
239 case hive_t_resource_requirements_list:
241 abort (); /* internal error - should not happen */
247 start_value (writer, key, type, "base64");
248 XML_CHECK (xmlTextWriterWriteBase64, (writer, str, 0, len));
255 value_dword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
256 hive_type t, size_t len, const char *key, int32_t v)
258 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
259 start_value (writer, key, "int32", NULL);
260 XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi32, v));
266 value_qword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
267 hive_type t, size_t len, const char *key, int64_t v)
269 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
270 start_value (writer, key, "int64", NULL);
271 XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi64, v));
277 value_binary (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
278 hive_type t, size_t len, const char *key, const char *v)
280 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
281 start_value (writer, key, "binary", "base64");
282 XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
288 value_none (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
289 hive_type t, size_t len, const char *key, const char *v)
291 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
292 start_value (writer, key, "none", "base64");
293 if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
299 value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
300 hive_type t, size_t len, const char *key, const char *v)
302 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
309 case hive_t_dword_be:
312 case hive_t_expand_string:
314 case hive_t_multiple_strings:
315 abort (); /* internal error - should not happen */
317 case hive_t_resource_list: type = "resource-list"; break;
318 case hive_t_full_resource_description: type = "resource-description"; break;
319 case hive_t_resource_requirements_list: type = "resource-requirements"; break;
325 start_value (writer, key, type, "base64");
326 if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));