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.
29 #include <libxml/xmlwriter.h>
35 #define _(str) dgettext(PACKAGE, (str))
36 //#define N_(str) dgettext(PACKAGE, (str))
42 /* Callback functions. */
43 static int node_start (hive_h *, void *, hive_node_h, const char *name);
44 static int node_end (hive_h *, void *, hive_node_h, const char *name);
45 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);
46 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);
47 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);
48 static int value_dword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t);
49 static int value_qword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t);
50 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);
51 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);
52 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);
54 static struct hivex_visitor visitor = {
55 .node_start = node_start,
57 .value_string = value_string,
58 .value_multiple_strings = value_multiple_strings,
59 .value_string_invalid_utf16 = value_string_invalid_utf16,
60 .value_dword = value_dword,
61 .value_qword = value_qword,
62 .value_binary = value_binary,
63 .value_none = value_none,
64 .value_other = value_other
67 #define XML_CHECK(proc, args) \
69 if ((proc args) == -1) { \
70 fprintf (stderr, _("%s: failed to write XML document\n"), #proc); \
71 exit (EXIT_FAILURE); \
76 main (int argc, char *argv[])
78 setlocale (LC_ALL, "");
79 bindtextdomain (PACKAGE, LOCALEBASEDIR);
86 while ((c = getopt (argc, argv, "dk")) != EOF) {
89 open_flags |= HIVEX_OPEN_DEBUG;
92 visit_flags |= HIVEX_VISIT_SKIP_BAD;
95 fprintf (stderr, "hivexml [-dk] regfile > output.xml\n");
100 if (optind + 1 != argc) {
101 fprintf (stderr, _("hivexml: missing name of input file\n"));
105 hive_h *h = hivex_open (argv[optind], open_flags);
107 perror (argv[optind]);
111 /* Note both this macro, and xmlTextWriterStartDocument leak memory. There
112 * doesn't seem to be any way to recover that memory, but it's not a
117 xmlTextWriterPtr writer;
118 writer = xmlNewTextWriterFilename ("/dev/stdout", 0);
119 if (writer == NULL) {
120 fprintf (stderr, _("xmlNewTextWriterFilename: failed to create XML writer\n"));
124 XML_CHECK (xmlTextWriterStartDocument, (writer, NULL, "utf-8", NULL));
125 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "hive"));
127 if (hivex_visit (h, &visitor, sizeof visitor, writer, visit_flags) == -1) {
128 perror (argv[optind]);
132 if (hivex_close (h) == -1) {
133 perror (argv[optind]);
137 XML_CHECK (xmlTextWriterEndElement, (writer));
138 XML_CHECK (xmlTextWriterEndDocument, (writer));
139 xmlFreeTextWriter (writer);
145 node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name)
147 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
148 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "node"));
149 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "name", BAD_CAST name));
154 node_end (hive_h *h, void *writer_v, hive_node_h node, const char *name)
156 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
157 XML_CHECK (xmlTextWriterEndElement, (writer));
162 start_value (xmlTextWriterPtr writer,
163 const char *key, const char *type, const char *encoding)
165 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "value"));
166 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "type", BAD_CAST type));
168 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "encoding", BAD_CAST encoding));
170 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "key", BAD_CAST key));
171 else /* default key */
172 XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "default", BAD_CAST "1"));
176 end_value (xmlTextWriterPtr writer)
178 XML_CHECK (xmlTextWriterEndElement, (writer));
182 value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
183 hive_type t, size_t len, const char *key, const char *str)
185 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
189 case hive_t_string: type = "string"; break;
190 case hive_t_expand_string: type = "expand"; break;
191 case hive_t_link: type = "link"; break;
196 case hive_t_dword_be:
197 case hive_t_multiple_strings:
198 case hive_t_resource_list:
199 case hive_t_full_resource_description:
200 case hive_t_resource_requirements_list:
202 abort (); /* internal error - should not happen */
208 start_value (writer, key, type, NULL);
209 XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST str));
215 value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node,
216 hive_value_h value, hive_type t, size_t len,
217 const char *key, char **argv)
219 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
220 start_value (writer, key, "string-list", NULL);
223 for (i = 0; argv[i] != NULL; ++i) {
224 XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "string"));
225 XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST argv[i]));
226 XML_CHECK (xmlTextWriterEndElement, (writer));
234 value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node,
235 hive_value_h value, hive_type t, size_t len,
237 const char *str /* original data */)
239 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
243 case hive_t_string: type = "bad-string"; break;
244 case hive_t_expand_string: type = "bad-expand"; break;
245 case hive_t_link: type = "bad-link"; break;
246 case hive_t_multiple_strings: type = "bad-string-list"; break;
251 case hive_t_dword_be:
252 case hive_t_resource_list:
253 case hive_t_full_resource_description:
254 case hive_t_resource_requirements_list:
256 abort (); /* internal error - should not happen */
262 start_value (writer, key, type, "base64");
263 XML_CHECK (xmlTextWriterWriteBase64, (writer, str, 0, len));
270 value_dword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
271 hive_type t, size_t len, const char *key, int32_t v)
273 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
274 start_value (writer, key, "int32", NULL);
275 XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi32, v));
281 value_qword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
282 hive_type t, size_t len, const char *key, int64_t v)
284 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
285 start_value (writer, key, "int64", NULL);
286 XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi64, v));
292 value_binary (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
293 hive_type t, size_t len, const char *key, const char *v)
295 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
296 start_value (writer, key, "binary", "base64");
297 XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
303 value_none (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
304 hive_type t, size_t len, const char *key, const char *v)
306 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
307 start_value (writer, key, "none", "base64");
308 if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
314 value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
315 hive_type t, size_t len, const char *key, const char *v)
317 xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
324 case hive_t_dword_be:
327 case hive_t_expand_string:
329 case hive_t_multiple_strings:
330 abort (); /* internal error - should not happen */
332 case hive_t_resource_list: type = "resource-list"; break;
333 case hive_t_full_resource_description: type = "resource-description"; break;
334 case hive_t_resource_requirements_list: type = "resource-requirements"; break;
340 start_value (writer, key, type, "base64");
341 if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));