mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
This commit adds the calls to setlocale &c to all of the current C programs. It also adds l10n support to hivexget and hivexml which lacked them previously. To test this, try: LANG=pa_IN.UTF-8 guestfish --cmd-help (You can only do this test after installing the package, or at least the 'pa.mo' mo-file in the correct place).
346 lines
11 KiB
C
346 lines
11 KiB
C
/* hivexml - Convert Windows Registry "hive" to XML file.
|
|
* Copyright (C) 2009 Red Hat Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <inttypes.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include <libxml/xmlwriter.h>
|
|
|
|
#include "hivex.h"
|
|
|
|
#ifdef HAVE_GETTEXT
|
|
#include "gettext.h"
|
|
#define _(str) dgettext(PACKAGE, (str))
|
|
//#define N_(str) dgettext(PACKAGE, (str))
|
|
#else
|
|
#define _(str) str
|
|
//#define N_(str) str
|
|
#endif
|
|
|
|
/* Callback functions. */
|
|
static int node_start (hive_h *, void *, hive_node_h, const char *name);
|
|
static int node_end (hive_h *, void *, hive_node_h, const char *name);
|
|
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);
|
|
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);
|
|
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);
|
|
static int value_dword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int32_t);
|
|
static int value_qword (hive_h *, void *, hive_node_h, hive_value_h, hive_type t, size_t len, const char *key, int64_t);
|
|
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);
|
|
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);
|
|
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);
|
|
|
|
static struct hivex_visitor visitor = {
|
|
.node_start = node_start,
|
|
.node_end = node_end,
|
|
.value_string = value_string,
|
|
.value_multiple_strings = value_multiple_strings,
|
|
.value_string_invalid_utf16 = value_string_invalid_utf16,
|
|
.value_dword = value_dword,
|
|
.value_qword = value_qword,
|
|
.value_binary = value_binary,
|
|
.value_none = value_none,
|
|
.value_other = value_other
|
|
};
|
|
|
|
#define XML_CHECK(proc, args) \
|
|
do { \
|
|
if ((proc args) == -1) { \
|
|
fprintf (stderr, _("%s: failed to write XML document\n"), #proc); \
|
|
exit (EXIT_FAILURE); \
|
|
} \
|
|
} while (0)
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
setlocale (LC_ALL, "");
|
|
bindtextdomain (PACKAGE, LOCALEBASEDIR);
|
|
textdomain (PACKAGE);
|
|
|
|
int c;
|
|
int open_flags = 0;
|
|
int visit_flags = 0;
|
|
|
|
while ((c = getopt (argc, argv, "dk")) != EOF) {
|
|
switch (c) {
|
|
case 'd':
|
|
open_flags |= HIVEX_OPEN_DEBUG;
|
|
break;
|
|
case 'k':
|
|
visit_flags |= HIVEX_VISIT_SKIP_BAD;
|
|
break;
|
|
default:
|
|
fprintf (stderr, "hivexml [-dk] regfile > output.xml\n");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
if (optind + 1 != argc) {
|
|
fprintf (stderr, _("hivexml: missing name of input file\n"));
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
hive_h *h = hivex_open (argv[optind], open_flags);
|
|
if (h == NULL) {
|
|
perror (argv[optind]);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
/* Note both this macro, and xmlTextWriterStartDocument leak memory. There
|
|
* doesn't seem to be any way to recover that memory, but it's not a
|
|
* large amount.
|
|
*/
|
|
LIBXML_TEST_VERSION;
|
|
|
|
xmlTextWriterPtr writer;
|
|
writer = xmlNewTextWriterFilename ("/dev/stdout", 0);
|
|
if (writer == NULL) {
|
|
fprintf (stderr, _("xmlNewTextWriterFilename: failed to create XML writer\n"));
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
XML_CHECK (xmlTextWriterStartDocument, (writer, NULL, "utf-8", NULL));
|
|
XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "hive"));
|
|
|
|
if (hivex_visit (h, &visitor, sizeof visitor, writer, visit_flags) == -1) {
|
|
perror (argv[optind]);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
if (hivex_close (h) == -1) {
|
|
perror (argv[optind]);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
XML_CHECK (xmlTextWriterEndElement, (writer));
|
|
XML_CHECK (xmlTextWriterEndDocument, (writer));
|
|
xmlFreeTextWriter (writer);
|
|
|
|
exit (EXIT_SUCCESS);
|
|
}
|
|
|
|
static int
|
|
node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "node"));
|
|
XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "name", BAD_CAST name));
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
node_end (hive_h *h, void *writer_v, hive_node_h node, const char *name)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
XML_CHECK (xmlTextWriterEndElement, (writer));
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
start_value (xmlTextWriterPtr writer,
|
|
const char *key, const char *type, const char *encoding)
|
|
{
|
|
XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "value"));
|
|
XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "type", BAD_CAST type));
|
|
if (encoding)
|
|
XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "encoding", BAD_CAST encoding));
|
|
if (*key)
|
|
XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "key", BAD_CAST key));
|
|
else /* default key */
|
|
XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "default", BAD_CAST "1"));
|
|
}
|
|
|
|
static void
|
|
end_value (xmlTextWriterPtr writer)
|
|
{
|
|
XML_CHECK (xmlTextWriterEndElement, (writer));
|
|
}
|
|
|
|
static int
|
|
value_string (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
|
|
hive_type t, size_t len, const char *key, const char *str)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
const char *type;
|
|
|
|
switch (t) {
|
|
case hive_t_string: type = "string"; break;
|
|
case hive_t_expand_string: type = "expand"; break;
|
|
case hive_t_link: type = "link"; break;
|
|
|
|
case hive_t_none:
|
|
case hive_t_binary:
|
|
case hive_t_dword:
|
|
case hive_t_dword_be:
|
|
case hive_t_multiple_strings:
|
|
case hive_t_resource_list:
|
|
case hive_t_full_resource_description:
|
|
case hive_t_resource_requirements_list:
|
|
case hive_t_qword:
|
|
abort (); /* internal error - should not happen */
|
|
|
|
default:
|
|
type = "unknown";
|
|
}
|
|
|
|
start_value (writer, key, type, NULL);
|
|
XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST str));
|
|
end_value (writer);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_multiple_strings (hive_h *h, void *writer_v, hive_node_h node,
|
|
hive_value_h value, hive_type t, size_t len,
|
|
const char *key, char **argv)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
start_value (writer, key, "string-list", NULL);
|
|
|
|
size_t i;
|
|
for (i = 0; argv[i] != NULL; ++i) {
|
|
XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "string"));
|
|
XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST argv[i]));
|
|
XML_CHECK (xmlTextWriterEndElement, (writer));
|
|
}
|
|
|
|
end_value (writer);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_string_invalid_utf16 (hive_h *h, void *writer_v, hive_node_h node,
|
|
hive_value_h value, hive_type t, size_t len,
|
|
const char *key,
|
|
const char *str /* original data */)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
const char *type;
|
|
|
|
switch (t) {
|
|
case hive_t_string: type = "bad-string"; break;
|
|
case hive_t_expand_string: type = "bad-expand"; break;
|
|
case hive_t_link: type = "bad-link"; break;
|
|
case hive_t_multiple_strings: type = "bad-string-list"; break;
|
|
|
|
case hive_t_none:
|
|
case hive_t_binary:
|
|
case hive_t_dword:
|
|
case hive_t_dword_be:
|
|
case hive_t_resource_list:
|
|
case hive_t_full_resource_description:
|
|
case hive_t_resource_requirements_list:
|
|
case hive_t_qword:
|
|
abort (); /* internal error - should not happen */
|
|
|
|
default:
|
|
type = "unknown";
|
|
}
|
|
|
|
start_value (writer, key, type, "base64");
|
|
XML_CHECK (xmlTextWriterWriteBase64, (writer, str, 0, len));
|
|
end_value (writer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_dword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
|
|
hive_type t, size_t len, const char *key, int32_t v)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
start_value (writer, key, "int32", NULL);
|
|
XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi32, v));
|
|
end_value (writer);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_qword (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
|
|
hive_type t, size_t len, const char *key, int64_t v)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
start_value (writer, key, "int64", NULL);
|
|
XML_CHECK (xmlTextWriterWriteFormatString, (writer, "%" PRIi64, v));
|
|
end_value (writer);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_binary (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
|
|
hive_type t, size_t len, const char *key, const char *v)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
start_value (writer, key, "binary", "base64");
|
|
XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
|
|
end_value (writer);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_none (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
|
|
hive_type t, size_t len, const char *key, const char *v)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
start_value (writer, key, "none", "base64");
|
|
if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
|
|
end_value (writer);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
value_other (hive_h *h, void *writer_v, hive_node_h node, hive_value_h value,
|
|
hive_type t, size_t len, const char *key, const char *v)
|
|
{
|
|
xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v;
|
|
const char *type;
|
|
|
|
switch (t) {
|
|
case hive_t_none:
|
|
case hive_t_binary:
|
|
case hive_t_dword:
|
|
case hive_t_dword_be:
|
|
case hive_t_qword:
|
|
case hive_t_string:
|
|
case hive_t_expand_string:
|
|
case hive_t_link:
|
|
case hive_t_multiple_strings:
|
|
abort (); /* internal error - should not happen */
|
|
|
|
case hive_t_resource_list: type = "resource-list"; break;
|
|
case hive_t_full_resource_description: type = "resource-description"; break;
|
|
case hive_t_resource_requirements_list: type = "resource-requirements"; break;
|
|
|
|
default:
|
|
type = "unknown";
|
|
}
|
|
|
|
start_value (writer, key, type, "base64");
|
|
if (len > 0) XML_CHECK (xmlTextWriterWriteBase64, (writer, v, 0, len));
|
|
end_value (writer);
|
|
|
|
return 0;
|
|
}
|